1. 问题
在真实的使用过程中,可能不同的 mapper 接口使用的 sqlSessionFactory
不一样。就比如下面这个例子。
1
2
3
4
5
6
7
8
9
| // 这个注解虽然可以指定 sqlSessionFactory, 但是最终使用的 configuration 对象是同一份。
@MapperScan("com.ooooo.**.mapper1")
@MapperScan("com.ooooo.**.mapper2")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
|
2. 解决方式
可以使用 MapperFactoryBean
来扩展,下面我给出相应的示例代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
| @Configuration
public class ComponentConfigMybatiPlusConfiguration {
@Getter
public static SqlSessionFactory sqlSessionFactory;
@Bean
public MapperFactoryBean<ComponentTreeMapper> componentTreeMapper() {
return createMapper(ComponentTreeMapper.class);
}
private <T> MapperFactoryBean<T> createMapper(Class<T> clazz) {
MapperFactoryBean<T> factoryBean = new MapperFactoryBean<>(clazz);
factoryBean.setSqlSessionFactory(sqlSessionFactory());
return factoryBean;
}
private synchronized SqlSessionFactory sqlSessionFactory() {
if (sqlSessionFactory != null) {
return sqlSessionFactory;
}
// 使用默认的dataSource
DataSource dataSource = SpringUtil.getBean(DataSource.class);
Environment environment = new Environment(COMPONENT_CONFIG, new SpringManagedTransactionFactory(), dataSource);
// build configuration
MybatisConfiguration configuration = new MybatisConfiguration();
configuration.setEnvironment(environment);
configuration.setCacheEnabled(false);
configuration.setLocalCacheScope(LocalCacheScope.STATEMENT);
setInterceptors(configuration);
setMapperLocations(configuration, new String[]{"classpath*:/mapper/**/*.xml"});
setGlobalConfig(configuration);
// factory
sqlSessionFactory = new MybatisSqlSessionFactoryBuilder().build(configuration);
return sqlSessionFactory;
}
private void setInterceptors(MybatisConfiguration configuration) {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
configuration.addInterceptor(mybatisPlusInterceptor);
}
private void setMapperLocations(MybatisConfiguration configuration, String[] mapperLocations) {
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
for (String mapperLocation : mapperLocations) {
try {
Resource[] resources = resourceResolver.getResources(mapperLocation);
for (Resource resource : resources) {
if (resource.exists()) {
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(resource.getInputStream(),
configuration, resource.toString(), configuration.getSqlFragments());
xmlMapperBuilder.parse();
}
}
} catch (IOException ignored) {
}
}
}
private void setGlobalConfig(MybatisConfiguration configuration) {
GlobalConfig globalConfig = GlobalConfigUtils.getGlobalConfig(configuration);
// MetaObjectHandler
globalConfig.setMetaObjectHandler(new ComponentMetaObjectHandler());
}
}
|
手动创建 Mapper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| // 用法
DataSource dataSource = DBUtil.buildDataSource(dbProperties);
SqlSession sqlSession = DBUtil.buildSqlSession(dbProperties.getName(), dataSource,
MockInfoMapper.class);
mockInfoMapper = sqlSession.getMapper(MockInfoMapper.class);
// 工具类
public class DBUtil {
public static DataSource buildDataSource(AbstractDBProperties dbProperties) {
HikariConfig config = new HikariConfig();
config.setPoolName("pool-" + dbProperties.getName());
config.setDriverClassName(dbProperties.getDriverClassName());
config.setJdbcUrl(dbProperties.getUrl());
config.setUsername(dbProperties.getUsername());
config.setPassword(dbProperties.getPassword());
return new HikariDataSource(config);
}
public static SqlSessionTemplate buildSqlSession(String id, DataSource dataSource, Class<?>... mapperClazz) {
Environment environment = new Environment(id, new SpringManagedTransactionFactory(), dataSource);
MybatisConfiguration configuration = new MybatisConfiguration(environment);
if (ArrayUtil.isNotEmpty(mapperClazz)) {
for (Class<?> clazz : mapperClazz) {
configuration.addMapper(clazz);
}
}
configuration.addInterceptor(buildInterceptor());
SqlSessionFactory sqlSessionFactory = new MybatisSqlSessionFactoryBuilder().build(configuration);
return new SqlSessionTemplate(sqlSessionFactory);
}
private static MybatisPlusInterceptor buildInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
|