在醒目中需要一个接口方法里操作多个数据库,因此产生多数据源切换问题;
采用 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
加上这个注解以后执行代码,解决问题。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于