springboot-Mybatis多数据源配置

环境信息:

1
2
Spring Boot:1.3.5
Java:1.7

配置信息

application.yml配置文件配置:

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
# SPRING PROFILES
spring:
datasource:
# 主数据源配置信息
primaryDataSource:
url: jdbc:oracle:thin:@192.168.10.111:1521:orcl
username: username
password: password
connectionTestQuery: SELECT 1+1 FROM DUAL
dataSourceClassName: oracle.jdbc.pool.OracleDataSource
typeAliasesPackage: com.hhly.template.entity.database
mapperLocations: classpath:com/hhly/template/dao/database/*.xml
configLocation: classpath:com/hhly/template/config/mybatis/mybatis-config.xml
# 中间库数据源配置信息
middleDataSource:
dataSourceClassName: oracle.jdbc.pool.OracleDataSource
url: jdbc:oracle:thin:@192.168.2.222:1521:orcl
username: username
password: password
max-idle: 10
max-wait: 10000
min-idle: 5
initial-size: 5
test-on-borrow: false
test-while-idle: true
time-between-eviction-runs-millis: 18800
cachePrepStmts: true
prepStmtsSize: 250
prepStmtsCacheSqlLimit: 2048
userServerPrepStmts: true
connectionTestQuery: SELECT 1+1 FROM DUAL
typeAliasesPackage: com.hhly.template.entity.middatabase
mapperLocations: classpath:com/hhly/template/dao/middatabase/*.xml
configLocation: classpath:com/hhly/template/config/mybatis/mybatis-config.xml

数据源1配置信息:

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
/**
* @ClassName: MybatisConfiguration
* @Description: 集成Mybatis
* @author Yue Chang
* @date 2016年9月7日 下午3:35:53
* @since 1.0
*/
@Configuration
@ConditionalOnClass({ EnableTransactionManagement.class, EntityManager.class })
@MapperScan(basePackages = { "com.hhly.template.dao.database" },sqlSessionFactoryRef="primarySqlSessionFactory")
public class PrimaryMybatisConfiguration implements EnvironmentAware {

private static Log logger = LogFactory.getLog(PrimaryMybatisConfiguration.class);

private RelaxedPropertyResolver propertyResolver;

private Environment env;

public void setEnvironment(Environment environment) {
this.env = environment;
this.propertyResolver = new RelaxedPropertyResolver(environment, "spring.datasource.primaryDataSource.");
}

@Bean(name = "primaryDataSource",destroyMethod="shutdown")
@Primary
public DataSource dataSource() {
logger.info("Configruing primaryDataSource start...");
HikariConfig config = new HikariConfig();
config.setDataSourceClassName(propertyResolver.getProperty("dataSourceClassName"));
config.addDataSourceProperty("url", propertyResolver.getProperty("url"));
config.setUsername(propertyResolver.getProperty("username"));
config.setPassword(propertyResolver.getProperty("password"));
config.setConnectionTestQuery(propertyResolver.getProperty("connectionTestQuery"))
logger.info("Configruing primaryDataSource end...");
return new HikariDataSource(config);
}

@Bean(name = "primarySqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory() {
try {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setTypeAliasesPackage(propertyResolver.getProperty("typeAliasesPackage"));
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(propertyResolver.getProperty("mapperLocations")));
sessionFactory.setConfigLocation(
new DefaultResourceLoader().getResource(propertyResolver.getProperty("configLocation")));

logger.info("初始化sqlSessionFactory成功!");
return sessionFactory.getObject();
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
return null;
}
}

@Bean(name = "primaryTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}

数据源2配置信息:

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
/**
* @ClassName: MiddleMybatisConfiguration
* @Description: 中间库数据源配置
* @author Yue Chang
* @date 2016年12月1日 下午3:33:26
* @since 1.0
*/
@Configuration
@ConditionalOnClass({ EnableTransactionManagement.class, EntityManager.class })
@MapperScan(basePackages = { "com.hhly.template.dao.middatabase" },sqlSessionFactoryRef="midSqlSessionFactory")
public class MiddleMybatisConfiguration implements EnvironmentAware {

private static Log logger = LogFactory.getLog(MiddleMybatisConfiguration.class);

private RelaxedPropertyResolver propertyResolver;

private Environment env;

public void setEnvironment(Environment environment) {
this.env = environment;
this.propertyResolver = new RelaxedPropertyResolver(environment, "spring.datasource.middleDataSource.");
}

@Bean(name = "middleDataSource",destroyMethod="shutdown")
public DataSource dataSource() {
logger.info("Configruing MiddleDataSource start...");
HikariConfig config = new HikariConfig();
config.setDataSourceClassName(propertyResolver.getProperty("dataSourceClassName"));
config.addDataSourceProperty("url", propertyResolver.getProperty("url"));
config.setUsername(propertyResolver.getProperty("username"));
config.setPassword(propertyResolver.getProperty("password"));
config.setConnectionTestQuery(propertyResolver.getProperty("connectionTestQuery"));
logger.info("Configruing MiddleDataSource end...");
return new HikariDataSource(config);
}

@Bean(name = "midSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory() {
try {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setTypeAliasesPackage(propertyResolver.getProperty("typeAliasesPackage"));
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(propertyResolver.getProperty("mapperLocations")));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(propertyResolver.getProperty("configLocation")));

logger.info("初始化sqlSessionFactory成功!");
return sessionFactory.getObject();
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
return null;
}
}

@Bean(name = "midTransactionManager")
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}

说明:
1、MapperScan中的basePackages 需要不同的目录
2、sqlSessionFactory和treansactionManager中如果使用下面方式可能会产生循环引用警告

1
2
3
4
5
6
7
@Bean(name = "primaryTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager(@Qualifier("primaryDataSource") DataSource primaryDataSource) {...}

@Bean(name = "primarySqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("primaryDataSource") DataSource primaryDataSource) {...}

警告信息如下:

1
2016-12-05 10:05:36 [main] WARN  org.springframework.beans.factory.support.DefaultListableBeanFactory -Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dictionaryMapper' defined in file [D:\neon-workspace\template\target\classes\com\hhly\template\dao\database\DictionaryMapper.class]: Cannot resolve reference to bean 'primarySqlSessionFactory' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'primarySqlSessionFactory': Requested bean is currently in creation: Is there an unresolvable circular reference?

解决办法:

1、将dataSouce 在其他类中定义,再注入;
2、去掉参数,需要dataSource的时候,通过dataSource()方法获得,只会初始化一次。