基本就是使用AbstractRoutingDataSource
实现的
继承该类,实现一个抽象方法
@Override
protected Object determineCurrentLookupKey() {
return name;
}
抽象方法返回要使用的 dataSource 的名字。其中使用 ThreadLocal 来保存当前使用的名字。
/**
* @author dengqn 2019/12/25-11:15
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
public static final ThreadLocal<String> context = new ThreadLocal<>();
public static final String MAIN_DATA_SOURCE = "mainDataSource";
public static final String DATA_SOURCE_240 = "dataSource240";
public static void setDataSource(String type) {
context.set(type);
}
public static String getDataSource() {
return context.get();
}
public static void clearDataSource() {
context.remove();
}
@Override
protected Object determineCurrentLookupKey() {
return context.get();
}
}
然后配置多个 dataSource, 让他持有 (有一个 map 存放),每个 dataSource 有不同的名字。
<bean id="dataSource" class="com.boyasoftware.datasource.DynamicDataSource">
<property name="defaultTargetDataSource" ref="mainDataSource"/>
<property name="targetDataSources">
<map>
<entry key="mainDataSource" value-ref="mainDataSource"/>
<entry key="dataSource240" value-ref="dataSource240"/>
</map>
</property>
</bean>
注意的是,如果当前 ThreadLocal 返回的 name 找不到,会使用默认的 DataSource.
然后就可以使用我们自定义的这个可变的 dataSource 了,而且切换的时候线程之间不会互相影响。
使用的时候就是直接切换就行了。
DynamicDataSource.clearDataSource();
DynamicDataSource.setDataSource(DynamicDataSource.DATA_SOURCE_240);
// 需要切换查询的业务代码
DynamicDataSource.clearDataSource();
DynamicDataSource.setDataSource(DynamicDataSource.MAIN_DATA_SOURCE);