SpringBoot 多数据源切换
抽象类AbstractRoutingDataSource,通过扩展这个类实现根据不同的请求切换数据源。
通过determineCurrentLookupKey()方法获取一个key,
通过key从resolvedDataSources中获取数据源DataSource对象。determineCurrentLookupKey()是个抽象方法,需要继承AbstractRoutingDataSource的类实现;
而resolvedDataSources是一个Map<Object, DataSource>,里面应该保存当前所有可切换的数据源。
- 定义一个DynamicDataSource 继承 AbstractRoutingDataSource 类
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final Logger logger =LoggerFactory.getLogger(DynamicDataSource.class);
@Override
protected Object determineCurrentLookupKey() {
// 从自定义的位置获取数据源标识
// logger.info("当前数据源:{}", DynamicDataSourceHolder.getDataSource());
return DynamicDataSourceHolder.getDataSource();
}
}
- 定义 DynamicDataSourceHolder 处理数据源标识KEY
public class DynamicDataSourceHolder {
/**
* 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰
*/
private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal<String>();
public static String getDataSource() {
return THREAD_DATA_SOURCE.get();
}
public static void setDataSource(String dataSource) {
THREAD_DATA_SOURCE.set(dataSource);
}
public static void clearDataSource() {
THREAD_DATA_SOURCE.remove();
}
}
- 数据源config配置
/**
* 数据源配置
*/
@Configuration
public class DataSourceConfiguration {
@Bean
@ConfigurationProperties("spring.datasource.mysql")
public DataSourceProperties mysqlDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("spring.datasource.mysql.configuration")
public DruidDataSource mysqlDataSource() {
return mysqlDataSourceProperties().initializeDataSourceBuilder().type(DruidDataSource.class).build();
}
@Bean
@ConfigurationProperties("spring.datasource.oracle")
public DataSourceProperties oracleDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("spring.datasource.oracle.configuration")
public DruidDataSource oracleDataSource() {
return oracleDataSourceProperties().initializeDataSourceBuilder().type(DruidDataSource.class).build();
}
@Bean
@Primary
public DynamicDataSource dataSource(DataSource mysqlDataSource, DataSource oracleDataSource) {
Map<Object, Object> targetDataSources = new HashMap<>(3);
targetDataSources.put("mysql", mysqlDataSource);
targetDataSources.put("oracle", oracleDataSource);
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.setDefaultTargetDataSource(mysqlDataSource);
return dynamicDataSource;
}
- application.properties
spring.datasource.mysql.username=xx
spring.datasource.mysql.password=xx
spring.datasource.mysql.url=jdbc:mysql://127.0.0.1:22/xxx?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&failOverReadOnly=false&rewriteBatchedStatements=true
spring.datasource.mysql.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.mysql.configuration.initialSize=5
spring.datasource.mysql.configuration.minIdle=5
spring.datasource.mysql.configuration.maxActive=500