springboot-mybatis-druid多数据源配置
在项目中经常会连接多个数据源,我结合了网上的一些示例和实际项目中的使用经验,做了些小小的改进,使配置更加简化了一下。先给出多数据源的配置:
spring:
application:
name: multiDatasource
datasource:
dbone:
url: jdbc:mysql://172.17.10.150:3306/dbone?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
dbtwo:
url: jdbc:mysql://172.17.10.150:3306/dbtwo?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
dbthree:
url: jdbc:mysql://172.17.10.150:3306/dbthree?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
druid:
driver-class-name: com.mysql.jdbc.Driver
initial-size: 5
max-active: 100
min-idle: 5
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 30
filters: stat
这里涉及到对druid的改造,默认druid是不支持这种形式的配置,这里把数据库连接的url
、username
、password
三个参数单独提取出来单独配置,其它配置项作为公共部分,查看了一下druid-spring-boot-starter
的源码,它是通过DruidDataSourceWrapper
配置类自动创建了一个数据源,它继承了DruidDataSource
类,并实现了InitializingBean
接口。由于不需要自己数据源的配置功能,所以不需要引用druid-spring-boot-starter
包,我定了一个同名的DruidDataSourceWrapper
类,稍进行改造了一下,去掉了@ConfigurationProperties("spring.datasource.druid")
注解,将配置通过参数的形式传进来,手动创建数据源。主要代码如下:
public class DruidDataSourceWrapper extends DruidDataSource implements InitializingBean {
private DruidConfig druidConfig;
private DbConfig dbConfig;
public DruidDataSourceWrapper(DbConfig dbConfig, DruidConfig druidConfig){
this.dbConfig = dbConfig;
this.druidConfig = druidConfig;
}
@Override
public void afterPropertiesSet() throws Exception {
if (super.getUsername() == null) {
super.setUsername(dbConfig.getUsername());
}
if (super.getPassword() == null) {
super.setPassword(dbConfig.getPassword());
}
if (super.getUrl() == null) {
super.setUrl(dbConfig.getUrl());
}
if(druidConfig!=null){
BeanUtils.copyProperties(druidConfig, this);
}
}
@Autowired(required = false)
public void autoAddFilters(List<Filter> filters){
super.filters.addAll(filters);
}
/**
* @since 1.1.14
*/
@Override
public void setMaxEvictableIdleTimeMillis(long maxEvictableIdleTimeMillis) {
try {
super.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);
} catch (IllegalArgumentException ignore) {
super.maxEvictableIdleTimeMillis = maxEvictableIdleTimeMillis;
}
}
}
@Setter
@Getter
@Component
@ConfigurationProperties(prefix = "spring.datasource.druid")
public class DruidConfig {
private String driverClassName;
private int initialSize = 5;
private int maxActive = 100;
private int minIdle = 5;
private long maxWait = 60000;
private long timeBetweenEvictionRunsMillis = 60000;
private long minEvictableIdleTimeMillis = 300000;
private String validationQuery = "SELECT 'x'";
private boolean testWhileIdle = true;
private boolean testOnBorrow = false;
private boolean testOnReturn = false;
private boolean poolPreparedStatements = true;
private int maxPoolPreparedStatementPerConnectionSize = 30;
private String filters = "stat";
}
@Setter
@Getter
public class DbConfig {
private String url;
private String username;
private String password;
}
手动创建dbone数据源
@Configuration
@MapperScan(basePackages = {"cn.fetosoft.multi.data.dbone"},
sqlSessionFactoryRef = "dboneSqlSessionFactory")
public class DboneDatasourceConfig {
@Autowired
private DruidConfig druidConfig;
/**
* 数据源配置
* @return
*/
@Bean(name = "dboneConfig")
@ConfigurationProperties(prefix = "spring.datasource.dbone")
public DbConfig buildDbConfig(){
return new DbConfig();
}
/**
* 系统数据源
* @return
*/
@Bean(name = "dboneDataSource")
public DruidDataSource sysDataSource(@Qualifier("dboneConfig") DbConfig dbConfig){
return new DruidDataSourceWrapper(dbConfig, druidConfig);
}
/**
* 创建Mybatis的SqlSessionFactory
* @return
* @throws Exception
*/
@Bean("dboneSqlSessionFactory")
public SqlSessionFactory buildSqlSessionFactory(@Qualifier("dboneDataSource") DruidDataSource dataSource) throws Exception{
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
factoryBean.setMapperLocations(patternResolver.getResources("classpath:cn/fetosoft/multi/data/mapper/dbone/*.xml"));
factoryBean.setConfigLocation(patternResolver.getResource("classpath:mybatis-config.xml"));
return factoryBean.getObject();
}
}
@Configuration
@MapperScan(basePackages = {"cn.fetosoft.multi.data.dbone"},
sqlSessionFactoryRef = "dboneSqlSessionFactory")
public class DboneDatasourceConfig {
@Autowired
private DruidConfig druidConfig;
/**
* 数据源配置
* @return
*/
@Bean(name = "dboneConfig")
@ConfigurationProperties(prefix = "spring.datasource.dbone")
public DbConfig buildDbConfig(){
return new DbConfig();
}
/**
* 系统数据源
* @return
*/
@Bean(name = "dboneDataSource")
public DruidDataSource sysDataSource(@Qualifier("dboneConfig") DbConfig dbConfig){
return new DruidDataSourceWrapper(dbConfig, druidConfig);
}
/**
* 创建SqlSessionFactory
* @return
* @throws Exception
*/
@Bean("dboneSqlSessionFactory")
public SqlSessionFactory buildSqlSessionFactory(@Qualifier("dboneDataSource") DruidDataSource dataSource) throws Exception{
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
factoryBean.setMapperLocations(patternResolver.getResources("classpath:cn/fetosoft/multi/data/mapper/dbone/*.xml"));
factoryBean.setConfigLocation(patternResolver.getResource("classpath:mybatis-config.xml"));
return factoryBean.getObject();
}
}
``````java
@Configuration
@MapperScan(basePackages = {"cn.fetosoft.multi.data.dbone"},
sqlSessionFactoryRef = "dboneSqlSessionFactory")
public class DboneDatasourceConfig {
@Autowired
private DruidConfig druidConfig;
/**
* 数据源配置
* @return
*/
@Bean(name = "dboneConfig")
@ConfigurationProperties(prefix = "spring.datasource.dbone")
public DbConfig buildDbConfig(){
return new DbConfig();
}
/**
* 系统数据源
* @return
*/
@Bean(name = "dboneDataSource")
public DruidDataSource sysDataSource(@Qualifier("dboneConfig") DbConfig dbConfig){
return new DruidDataSourceWrapper(dbConfig, druidConfig);
}
/**
* 创建SqlSessionFactory
* @return
* @throws Exception
*/
@Bean("dboneSqlSessionFactory")
public SqlSessionFactory buildSqlSessionFactory(@Qualifier("dboneDataSource") DruidDataSource dataSource) throws Exception{
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
factoryBean.setMapperLocations(patternResolver.getResources("classpath:cn/fetosoft/multi/data/mapper/dbone/*.xml"));
factoryBean.setConfigLocation(patternResolver.getResource("classpath:mybatis-config.xml"));
return factoryBean.getObject();
}
}
完整demo源码下载地址:https://github.com/gbinb/multi-datasource