在醒目中需要一个接口方法里操作多个数据库,因此产生多数据源切换问题;
采用 spring + springMVC + mybatis,相关测试如下:
首先数数据源配置
``` 再来一个
```
接下来是数据源的切换类
public class MultipleDataSource extends AbstractRoutingDataSource {
public static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static final String dataSource1 = "dataSource1";
public static final String dataSource2 = "dataSource2";
/**
* 设置当前数据源
* @param dbType
*/
public static void setDbType(String dbType){
contextHolder.set(dbType);
}
/**
* 当前数据源
*/
public static String getDbType(){
return contextHolder.get();
}
@Override
protected Object determineCurrentLookupKey() {
return contextHolder.get();
}
使用 AOP 来实现动态切换 配置如下
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
<context:component-scan base-package="xx.xx.xx" />
<aop:aspectj-autoproxy proxy-target-class="true"/>
在配置 AOP 的时候需要注意的是我们是在 SpringMVC 上 aop 监测,那么所有的扫描注入都在 SpringMVC 的配置文件中完成,不要再 spring 的配置文件中完成,不然在开启代理后,是没有任何作用的。
AOP 实现类
@Component
@Aspect
public class MultipleDataSourceAspectAdvice {
//这里根据自己的业务选择切面的路径和数据源的设置
@Around("execution(* xx.xx.*.*(..))")
public Object doAround(ProceedingJoinPoint jp) throws Throwable {
String methodName=jp.getSignature().getName();
if("save".equals(methodName)){
MultipleDataSource.setDbType(MultipleDataSource.dataSource1);
System.out.println("设置dataSource1");
}else{
MultipleDataSource.setDbType(MultipleDataSource.dataSource2);
System.out.println("设置dataSource2");
}
return jp.proceed();
}
}
到这个时候,基本上的配置已经完成了,但是在使用过程中发现问题,已经设置了数据源,可是数据源是随机获取的,是什么原因呢?
最后经过查阅资料得知 Spring 的事务与数据源是绑定的,也就是说如果你开启了事务,那么数据源已经绑定了。那么这个时候,你在去切换数据源就无效了。也就是说要想有效,那么就要在事务开启之前就把数据源切换好。
在 Spring 中有一个注解是用来设置加载顺序的 @Order(?),把这个注解加载 AOP 的实现类上,参数 0.1.2 越小代表越先执行。d
加上这个注解以后执行代码,解决问题。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于