您现在的位置是:首页 > 文章详情

baomidou的dynamic-datasource读写分离实现和加入AOP根据方法名选择库

日期:2019-10-22点击:793

文档

https://gitee.com/baomidou/dynamic-datasource-spring-boot-starter/wikis/pages

maven

 <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>2.5.7</version> </dependency>

纯读写分离(mybatis环境)

场景:

  1. 在纯的读写分离环境,写操作全部是master,读操作全部是slave。
  2. 不想通过注解配置完成以上功能。

答:在mybatis环境下可以基于mybatis插件结合本数据源完成以上功能。 手动注入插件。

@Bean public MasterSlaveAutoRoutingPlugin masterSlaveAutoRoutingPlugin(){ return new MasterSlaveAutoRoutingPlugin(); }

默认主库名称master,从库名称slave。

问题

       我在配置好了之后,调试发现对数据库读的操作不得进入MasterSlaveAutoRoutingPlugin,而且进入了默认的库。只有写进入了MasterSlaveAutoRoutingPlugin中。当然也可以默认为从库,但是感觉就不是很好。

       于是我自定义了一个aop切面来,来完成库的选择,代码如下:

import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.context.annotation.Lazy; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; import lombok.extern.java.Log; /** * Copyright: Copyright (c) 2019 * <p> 说明:动态数据源配置 </P> * * @version: V1.0 * @author: BianPeng * */ @Aspect @Component @Order(0) @Lazy(false) @Log public class DataSourceAop{ private static final String MASTER = "master"; private static final String SLAVE = "slave"; @Pointcut("execution(* com.buybit.power.service..*.*(..)) || execution(* com.baomidou.mybatisplus.extension.service..*.*(..))") public void checkArgs() { } // 这里切到你的方法目录 @Before("checkArgs()") public void process(JoinPoint joinPoint) throws NoSuchMethodException, SecurityException { String methodName = joinPoint.getSignature().getName(); if (methodName.startsWith("get") || methodName.startsWith("count") || methodName.startsWith("find") || methodName.startsWith("list") || methodName.startsWith("select") || methodName.startsWith("check") || methodName.startsWith("page")) { log.info("当前执行的库:"+SLAVE); DynamicDataSourceContextHolder.push(SLAVE); } else { log.info("当前执行的库:"+MASTER); DynamicDataSourceContextHolder.push(MASTER); } } @After("checkArgs()") public void afterAdvice(){ DynamicDataSourceContextHolder.clear(); } }

但是发现,baomidou/dynamic-datasource自带的@DS没失去了着用,于是我把有@DS的类和方法排除掉,代码入下:

import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.context.annotation.Lazy; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; import lombok.extern.java.Log; /** * Copyright: Copyright (c) 2019 * <p> 说明:动态数据源配置 </P> * * @version: V1.0 * @author: BianPeng * */ @Aspect @Component @Order(0) @Lazy(false) @Log public class DataSourceAop{ private static final String MASTER = "master"; private static final String SLAVE = "slave"; @Pointcut("execution(* com.buybit.power.service..*.*(..)) || execution(* com.baomidou.mybatisplus.extension.service..*.*(..))") public void checkArgs() { } // 这里切到你的方法目录 @Before("checkArgs()") public void process(JoinPoint joinPoint) throws NoSuchMethodException, SecurityException { String methodName = joinPoint.getSignature().getName(); Class clazz = joinPoint.getTarget().getClass(); if(clazz.isAnnotationPresent(DS.class)){ //获取类上注解 return; } String targetName = clazz.getSimpleName(); Class[] parameterTypes = ((MethodSignature)joinPoint.getSignature()).getMethod().getParameterTypes(); Method methdo = clazz.getMethod(methodName,parameterTypes); if (methdo.isAnnotationPresent(DS.class)) { return; } if (methodName.startsWith("get") || methodName.startsWith("count") || methodName.startsWith("find") || methodName.startsWith("list") || methodName.startsWith("select") || methodName.startsWith("check") || methodName.startsWith("page")) { log.info("当前执行的库:"+SLAVE); DynamicDataSourceContextHolder.push(SLAVE); } else { log.info("当前执行的库:"+MASTER); DynamicDataSourceContextHolder.push(MASTER); } } @After("checkArgs()") public void afterAdvice(){ DynamicDataSourceContextHolder.clear(); } }

这样可以让你有@DS的注解依然生效,而且也会根据方法名来自动切换数据源。

原文链接:https://my.oschina.net/bianxin/blog/3120455
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章