https://blog.csdn.net/qq_18860653/article/details/80347583
需求描述
在我們的開發過程中,一個項目連接多個數據庫經常出現。在Spring+Mybatis的項目中,遇到這種情況該怎麼辦?
我整理了一下,基本上兩種方式去解決。
配置多個sqlSessionFactory
配置多個數據源使用AOP切換
配置多個sqlSessionFactory的方式實現多數據源配置
這種方式是比較簡單的,在xml中,配置多個sqlSessionFactory,每個sqlSessionFactory中配置不同的數據源,且加載不同的mapper(實例化好的mapper,數據源不再改變)。加載不同的mapper可以把不同的數據庫的mapper配置到不同目錄下加載,當然也可以用自己的規則。
配置多個數據源使用AOP切換
本文就着重講下這種方式。
在sqlSessionFactory中,我們可以配置數據源爲AbstractRoutingDataSource,這個數據源需要你自己去實現。
這個類也是多數據源配置的核心。從這個抽象類的字面意思就可以理解,這是一個路由數據源,可以切換不同的數據源。
下面是我的一種實現方式:
public class MultipleDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal dataSourceKey = new InheritableThreadLocal();
public static void setDataSourceKey(String dataSource) {
dataSourceKey.set(dataSource);
}
@Override
protected Object determineCurrentLookupKey() {
return dataSourceKey.get();
}
}
<bean id="multipleDataSource" class="top.yuyufeng.learn.jdbc.MultipleDataSource">
<property name="defaultTargetDataSource" ref="dataSource1"/>
<property name="targetDataSources">
<map>
<entry key="myDataSource1" value-ref="dataSource1"/>
<entry key="myDataSource2" value-ref="dataSource2"/>
</map>
</property>
</bean>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
如何切換?我們可以通過切面方式:
@Component
@Aspect
public class MultipleDataSourceAspectAdvice {
private static Map<String, String> classMap = new HashMap<>();
static {
classMap.put("top.yuyufeng.learn.dao.UserInfoDao", "myDataSource1");
classMap.put("top.yuyufeng.learn.dao.GoodInfoDao", "myDataSource2");
}
@Around("execution(* top.yuyufeng.learn.dao.*.*(..))")
public Object doAround(ProceedingJoinPoint jp) throws Throwable {
//根據Dao切換數據源
String clazzName = jp.getTarget().getClass().getName();
System.out.println(clazzName);
MultipleDataSource.setDataSourceKey(classMap.get(clazzName));
return jp.proceed();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
這種方式實現的優勢很多,通過路由可以實現負載等功能
當然,talk is cheap, show me the code
具體實現
https://gitee.com/mryyf/sample-tkmybatis-spring