二、Mybatis结合插件实现读写分离(动态切换数据源)、Aop切面使用注解实现动态数据源配置
(一)使用Mybatis插件
在继承之上修改,使用Mybatis插件(上一篇文章基础上修改:一、springboot druid连接池实现多数据源动态切换方式(继承接口:AbstractRoutingDataSource) - 代码红了一大片 - 博客园 (cnblogs.com))
添加一个对应的拦截器配置
@Intercepts( {@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}), @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
//在Mybatis中对操作的分类分为两种(update:增删改)(query:查) public class DynamicDataSourcePlugin implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 拿到当前方法(update、query)所有参数 Object[] objects = invocation.getArgs(); // MappedStatement 封装CRUD所有的元素和SQL MappedStatement ms = (MappedStatement) objects[0]; // 读方法 if (ms.getSqlCommandType().equals(SqlCommandType.SELECT)) { //在这里可以设置使用的数据源对象,这里的数据源对象是上一个加成类相同的数据源配置 DynamicDataSource.name.set("R1"); } else { // 写方法 DynamicDataSource.name.set("R3"); } // 修改当前线程要选择的数据源的key return invocation.proceed(); } @Override public Object plugin(Object target) { if (target instanceof Executor) { return Plugin.wrap(target, this); } else { return target; } } @Override public void setProperties(Properties properties) { } }
将对应的配置在配置类中使用@Bean注入到容器中
@Bean public Interceptor dynamicDataSourcePlugin(){ return new DynamicDataSourcePlugin(); }
(二)Aop切面注解实现(适用于不同的数据源)
注意:适用下面自动配置切面代理在主类上
@EnableAspectJAutoProxy(exposeProxy=true)

实现一个自定义注解:
//目标对象,可以是方法,可以是类,也可以设置为字段属性
@Target({ElementType.METHOD,ElementType.TYPE}) //保留级别: //SOURCE:注释将被编译器丢弃 //RUNTIME:注释将由编译器记录在类文件中,并在运行时由 VM 保留,因此可以反射性地读取它们 //CLASS:注释将由编译器记录在类文件中,但不需要在运行时由 VM 保留。这是默认行为。 @Retention(RetentionPolicy.RUNTIME) public @interface TargetDataSource { String value() default "R1"; }
实现一个切面:(确保在被注解修饰的类上可以被扫描到)
@Component
@Aspect
public class DynamicDataSourceAspect {
//within(com.zjl.datasources.controller.*)表示在项目中,controller下的所有包使用都会被扫描到,也可以不使用
//@annotation(ts)表示是注解的切面
//(JoinPoint point,TargetDataSource ts)表示切入点和扫描到的注解类(ts.value()注解中的value对象)
@Before("within(com.zjl.datasources.controller.*) && @annotation(ts)")
public void before(JoinPoint point, TargetDataSource ts){
String value = ts.value();
DynamicDataSource.name.set(value);
System.out.println(value);
}
}
(三)配置多个mybatis实现多数据源动态切换

浙公网安备 33010602011771号