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