基本就是使用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);