baomidou的dynamic-datasource读写分离实现和加入AOP根据方法名选择库
文档
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环境)
场景:
- 在纯的读写分离环境,写操作全部是master,读操作全部是slave。
- 不想通过注解配置完成以上功能。
答:在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的注解依然生效,而且也会根据方法名来自动切换数据源。
baomidou的dynamic-datasource读写分离实现和加入AOP根据方法名选择库的更多相关文章
- SSM/SSH框架的MySQL 读写分离实现的一种简单方法
简介 MySQL已经是使用最为广泛的一种数据库,往往实际使用过程中,为实现高可用及高性能,项目会采用主丛复制的方式实现读写分离.MySQL本身支持复制,通过简单的配置即可实现一主多从的配置,具体实现可 ...
- 【EFCore框架】支持多数库 、支持读写分离框架、支持事务提交保存、跨库实现事务
1.支持多数库: 数据库上下文实现 多数据支持: 2. 支持读写分离框架(支持多从库随机) 工作单元(以及仓储)实现读写分离 配置文件: 3. 支持事务提交保存 工作单元 实现事务数据统一提交保存 具 ...
- laravel(lumen)配置读写分离后,强制读主(写)库数据库,解决主从延迟问题
在Model里面加上下面这句,强制读主(写)库数据库,解决主从延迟问题. public static function boot() { //清空从连接,会自动使用主连接 DB::connection ...
- Springboot + Mysql8实现读写分离
在实际的生产环境中,为了确保数据库的稳定性,我们一般会给数据库配置双机热备机制,这样在master数据库崩溃后,slave数据库可以立即切换成主数据库,通过主从复制的方式将数据从主库同步至从库,在业务 ...
- 从零开始学 Java - Spring AOP 实现主从读写分离
深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...
- JAVA-mysql读写分离插件介绍
kingshard是一个由Go开发高性能MySQL Proxy项目,kingshard在满足基本的读写分离的功能上,致力于简化MySQL分库分表操作:能够让DBA通过kingshard轻松平滑地实现M ...
- Spring Boot2(四):使用Spring Boot多数据源实现读写分离
前言 实际业务场景中,不可能只有一个库,所以就有了分库分表,多数据源的出现.实现了读写分离,主库负责增改删,从库负责查询.这篇文章将实现Spring Boot如何实现多数据源,动态数据源切换,读写分离 ...
- Mybatis多数据源读写分离(注解实现)
#### Mybatis多数据源读写分离(注解实现) ------ 首先需要建立两个库进行测试,我这里使用的是master_test和slave_test两个库,两张库都有一张同样的表(偷懒,喜喜), ...
- 读写分离很难吗?springboot结合aop简单就实现了
目录 前言 环境部署 开始项目 注意 參考: 前言 入职新公司到现在也有一个月了,完成了手头的工作,前几天终于有时间研究下公司旧项目的代码.在研究代码的过程中,发现项目里用到了Spring Aop来实 ...
- 原理解密 → Spring AOP 实现动态数据源(读写分离),底层原理是什么
开心一刻 女孩睡醒玩手机,收到男孩发来一条信息:我要去跟我喜欢的人表白了! 女孩的心猛的一痛,回了条信息:去吧,祝你好运! 男孩回了句:但是我没有勇气说不来,怕被打! 女孩:没事的,我相信你!此时女孩 ...
随机推荐
- threejs 浏览器窗口resize变化 自适应 html 全屏
全屏:画布全屏和body页面全屏: // 导入 threejs import * as THREE from "three"; import { OrbitControls } f ...
- kotlin更多语言结构——>异常
异常类 Kotlin 中所有异常类都是 Throwable 类的子孙类.每个异常都有消息.堆栈回溯信息以及可选的原因 使用 throw-表达式来抛出异常 throw Exception("H ...
- docker打包镜像,上传镜像仓库,使用rancher发布
步骤一.首先将项目打包放在指定目录下 项目jar包名称为 micro-app.jar 步骤二.将jar包名称改为指定名称,执行命令 docker build -t micro-gateway: ...
- ERQ:32位转5位仅掉些许精度,来看看两段式后训练量化 | ICML 2024
后训练量化(PTQ)在视觉Transformer(ViTs)领域引起了广泛关注,因为它在模型压缩方面表现出了高效率.然而,现有的方法通常忽视了量化权重和激活之间复杂的相互依赖关系,导致了相当大的量化误 ...
- 警告:攻击者利用 SnoarQube 漏洞盗取国内多个机构的大量源码!
2021 年 10 月 22 日,国外知名媒体 cybernews 发文称,有未知攻击者攻击并渗透了博世 iSite 的服务器,并盗取了这家制造业巨头的 5G 物联网连接平台的源代码. 攻击者声称通过 ...
- MiGPT让你的小爱音响更聪明
大家好,我是晓凡. 今天要给大家带来一个超级有趣的开源项目MiGPT. 这个项目,简直就是给小爱音箱装上了超级大脑,让你的小爱音箱更聪明. 想象一下,当小爱音箱接入大模型后,上知天文,下知地理,从&q ...
- node.js安装及环境配置基于Windows系统
node.js安装及环境配置-Windows系统 1. 下载安装包 https://nodejs.org/zh-cn/download/ 根据自己电脑系统及位数选择,我的电脑是Windows系统.64 ...
- Linux基础-学会使用命令帮助
概述 使用 whatis 使用 man 查看命令程序路径 which 总结 参考资料 概述 Linux 命令及其参数繁多,大多数人都是无法记住全部功能和具体参数意思的.在 linux 终端,面对命令不 ...
- ubuntu16.04安装mmdetection库
一,前言 1.1,更新 pip 和 conda下载源 1.2,查看 conda 和 pip 版本 二,MMDetection 简介 三,MMDetection 安装 3.1,依赖环境 3.2,安装过程 ...
- 国内计算机领域相关的SCI和EI期刊,以及好中的SCI和EI期刊(不限国内外)
好中的: SCI刊: EI刊: EI会议: 参考: CCF发布计算领域高质量科技期刊分级目录 国内的: SCI-Expanded 1. <Journal of Computer Scie ...