配置文件方式,这里使用YMAL,你也可以使用传统的Properties,只要将:更换为.的形式即可。
spring:
datasource:
one:
setype: com.alibaba.druid.pool.DruidDataSource
url: 你的JDBC URL
username: 你的用户名
password: 你的密码
driver-class-name: com.mysql.jdbc.Driver
two:
setype: com.alibaba.druid.pool.DruidDataSource
url: 你的JDBC URL
username: 你的用户名
password: 你的密码
driver-class-name: com.mysql.jdbc.Driver
创建DynamicDataSource
类
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getType();
}
}
创建DataSourceContextHolder
类并使用ThreadLocal
来存放数据源类型变量
public class DataSourceContextHolder {
private static final Logger LOGGER = LoggerFactory.getLogger(ProductContextHolder.class);
public static final List<Object> supportList= new ArrayList<>();
// 线程本地环境
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setType(String type) {
contextHolder.set(type);
LOGGER.debug("==============切换数据源,类型:" + type + "================");
}
public static String getType() {
return (contextHolder.get());
}
public static void clear() {
contextHolder.remove();
}
public static boolean support(String type) {
return supportList.contains(type);
}
}
创建一个Configurer
来配置数据源,这里仅配置两个作为参考,如果你看过 使用Spring配置动态数据源实现读写分离 的话,你会觉得这非常简单,只不过是XML配置方式 =》 编程配置方式的转化。
有趣的是如果你要使用非默认数据源,如Druid,数据源配置项datasource.setype.com.alibaba.druid.pool.DruidDataSource
并不能很好工作,只能使用DataSourceBuilder
的时候显式指定,至少在Spring Boot 1.4是这样。
@Configuration
public class DataSourceConfigurer {
@Bean
@Primary
@ConfigurationProperties(prefix="spring.datasource.one")
public DataSource oneDataSource() {
return DataSourceBuilder
.create()
.type(DruidDataSource.class)
.build();
}
@Bean
@ConfigurationProperties(prefix="spring.datasource.two")
public DataSource twoDataSource() {
return DataSourceBuilder
.create()
.type(DruidDataSource.class)
.build();
}
@Bean
public DynamicDataSource dataSource(){
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> targetDataSources = Maps.newHashMap();
targetDataSources.put("one", oneDataSource());
targetDataSources.put("two", twoDataSource());
dynamicDataSource.setTargetDataSources(targetDataSources);
DataSourceContextHolder.supportList.addAll(targetDataSources.keySet());
return dynamicDataSource;
}
}
好了,动态数据源配置完成,至于在什么时候切换数据源根据你的实际情况而定,方式有很多,比如使用注解、做切面、用拦截器拦截参数等等,这里就不做赘述了。在使用void DataSourceContextHolder.setType(String type)
切换数据源前最好能调用boolean DataSourceContextHolder.support(String type)
判断是否支持该数据源。