SpringBoot 手动实现动态切换数据源 DynamicSource (中)

大家好,我是此林。

SpringBoot 手动实现动态切换数据源 DynamicSource (上)-CSDN博客

在上一篇博客中,我带大家手动实现了一个简易版的数据源切换实现,方便大家理解数据源切换的原理。今天我们来介绍一个开源的数据源切换框架,是baomidou 旗下和 Mybatis-plus 同级的开源框架:dynamic-datasource-spring-boot-starter。

1. 简介

dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。

其支持 Jdk 1.7+, SpringBoot 1.5.x 2.x.x 3.x.x
JPA用户不建议使用,JPA自带事务,无法连续切库。

2. 使用

下面基于SpringBoot2 做演示。

1.pom.xml

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

2.application.yml

spring:datasource:dynamic:primary: master #设置默认的数据源或者数据源组,默认值即为masterstrict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源datasource:master:url: jdbc:mysql://192.168.183.128:3306/userusername: rootpassword: 123456slave_1:url: jdbc:mysql://192.168.183.128:3307/userusername: rootpassword: 123456slave_2:url: jdbc:mysql://192.168.183.128:3308/userusername: rootpassword: 123456

参数说明:

以上会配置一个默认库master,一个组slave下有两个子库slave_1,slave_2

后续我们会使用AOP注解的方式指定数据源。

例如:@DS("master")、@DS("slave")

  1. 配置文件所有以下划线 _ 分割的数据源 首部 即为组的名称,相同组名称的数据源会放在一个组下。
  2. 切换数据源可以是组名,也可以是具体数据源名称。组名则切换时采用负载均衡算法切换。

例如:当我们使用@DS("slave")时,指定了组名  “slave”,那么它会采用负载均衡算法自动切换数据源。

因为我们后续希望实现Mysql主从读写分离,所有写操作走master数据库,所有读操作走slave从数据库。

3. 使用 @DS 切换数据源。

@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Overridepublic void insert(User user) {userMapper.insert(user);}@Override@DS("slave_1")public List<User> selectAll() {userMapper.selectAll();}@Override@DS("slave")public User selectById(Integer id) {return userMapper.selectById(id);}
}

说明:

insert() 方法没有加@DS,默认使用master数据库。

selectAll() 方法指定使用数据源slave_1

selectById() 使用slave组,自动负载均衡查询。

注:@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解

若要实现Mysql主从自动复制,还需要配置mysql主从复制,详情参考博客:

ShardingSphere5:Mysql主从集群搭建、读写分离_shardingsphere mysql读写分离-CSDN博客

其中SpringBoot配置 ShardingSphere5 这一块不用管,Mysql主从集群搭建是不变的。

4.其他实现

3. 底层原理

1. SpringBoot自动配置

我们找到 DynamicDataSourceAutoConfiguration.class。 这是框架的自动配置类。

这一段是从我们配置的application.yml 读取并设置相关属性,也就是我们配置的数据源信息。

具体的话,是赋值给 DynamicRoutingDataSource 这个对象。

2. 扫描@DS注解

这是 DynamicDataSourceAnnotationInterceptor 的 invoke 方法,典型的AOP。

在所有加了@DS的方法上,

1. 当执行目标方法的时候,会先获取到@DS("XXX")中数据源的名称,dsKey。

2. 然后再把dsKey 存到ThreadLocal中,也就是图中的DynamicDataSourceContextHolder。

3. 最后再开始执行目标方法。

3. DynamicRoutingDataSource

回到我们之前自动配置里说的 DynamicRoutingDataSource

观察 DynamicRoutingDataSource 的继承关系链,发现它实现了Spring的 DataSource 和 InitializingBean 接口。

这和我们上一篇博客手动实现数据源切换的思路是一样的。

在 DynamicRoutingDataSource 里,determineDataSource 从 ThreadLocal 里 获取到指定数据源名称

最后通过名称返回对应的DataSource数据源。

对比上一篇博客,

SpringBoot 手动实现动态切换数据源 DynamicSource (上)-CSDN博客

其实思路大差不差,只不过 dynamic-datasource-spring-boot-starter 更加完善,增加了AOP注解功能。

4. 无注解切换数据源

1. 自定义切面,结合 DynamicDatasourceNamedInterceptor ,对于所有以 select 方法开头的,设置使用 slave 数据源, 对于add、update、delete 开头的使用 master 数据源。

2. 自定义 Mybatis 拦截器,对于所有的写操作使用 master 数据源,所有读操作使用 slave 数据源。(即:把数据源标识写入 DynamicDataSourceContextHolder 中)。

3. 其他场景:SaaS多租户系统下,每个租户使用独立的数据库,那么可以要求前端携带请求头 “dsKey”。配置自定义拦截器,拦截请求,把dsKey 写入 DynamicDataSourceContextHolder。

今天的分享就到这里。

我是此林,关注我吧,带你看不一样的世界!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/491563.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

上海艾一公司-运维工程师知识点备战

1.AD域控&#xff08;ActionDirectory活动目录&#xff09; ad域的作用&#xff1a;批量管理主机和用户&#xff08;所以数量要多用这个才合适&#xff09; 前置1&#xff1a;VM安装Windows镜像 2.IT资产管理 3.会议室管理

构建一个rust生产应用读书笔记四(实战2)

此门课程学习采用actix-web框架完成一个生产级别的rust应用&#xff0c;在 actix-web 中&#xff0c;Extractors 是一个非常重要的概念&#xff0c;它们用于从传入的 HTTP 请求中提取特定的信息片段。actix-web 提供了多种内置的提取器&#xff0c;以满足常见的使用场景。说白了…

前端学习笔记-Vue篇-04

4 Vue中的ajax 4.1 解决开发环境Ajax跨域问题 vue脚手架配置代理 配置参考 | Vue CLI方法一&#xff1a;在vue.config.js中添加如下配置: module.exports {devServer: {proxy: http://localhost:4000} } 说明: 1.优点:配置简单&#xff0c;请求资源时直接发给前端(8080)即…

InnoDB事务系统(二):事务的实现

事务隔离性由锁来实现。原子性、一致性、持久性通过数据库的 redo log 和 undo log 来完成。 redo log 称为重做日志&#xff0c;用来保证事务的原子性和持久性。undo log 用来保证事务的一致性。 有的 DBA 或许会认为 undo 是 redo 的逆过程&#xff0c;其实不然。redo 和 u…

c++理解(三)

本文主要探讨c相关知识。 模板是对类型参数化 函数模板特化不是模板函数重载 allocator(空间配置器):内存开辟释放,对象构造析构 优先调用对象成员方法实现的运算符重载函数,其次全局作用域找 迭代器遍历访问元素,调用erase&#xff0c;insert方法后&#xff0c;当前位置到容器…

实训项目11基于51单片机的门禁监测系统设计

00 要求 基于51单片机和RFID模块实现门禁的设计。使之具有以下功能: 能够正常的读卡信息&#xff1b;在正常刷卡通过后&#xff0c;可以控制电子锁动作&#xff1b;在刷卡失败后&#xff0c;可以产生报警信号; 01 功能分析 读卡后会RFID会自动通过TXD&#xff08;串口&…

opencv——识别图片颜色并绘制轮廓

图像边缘检测 本实验要用到Canny算法&#xff0c;Canny边缘检测方法常被誉为边缘检测的最优方法。 首先&#xff0c;Canny算法的输入端应为图像的二值化结果&#xff0c;接收到二值化图像后&#xff0c;需要按照如下步骤进行&#xff1a; 高斯滤波。计算图像的梯度和方向。非极…

源码安装PHP-7.2.19

源码安装PHP-7.2.19 1.解压 tar -xjvf php-7.2.19.tar.bz2.编译 -prefix安装路径 cd php-7.2.19 ./configure --prefix/home/work/study 成功输出 3.make(构建) makemake testmake installlinux对php操作的一些命令 # 进入到php [rootvdb1 study]# cd php/ [rootvdb1 st…

数据库管理-第271期 Oracle 23ai:用MongoDB的方式来操作JSON二元性(20241214)

数据库管理271期 2024-12-14 数据库管理-第271期 Oracle 23ai&#xff1a;用MongoDB的方式来操作JSON二元性&#xff08;20241214&#xff09;1 初始化数据1.1 创建用户1.2 导入数据1.3 创建JSON关系二元性视图 2 创建ORDS服务2.1 下载JDK172.2 安装ORDS2.3 启用MongoDB API2.4…

2024 年的科技趋势

2024 年在科技领域有着诸多重大进展与突破。从人工智能、量子计算到基因组医学、可再生能源以及新兴技术重塑了众多行业。随着元宇宙等趋势的兴起以及太空探索取得的进步&#xff0c;未来在接下来的岁月里有望继续取得进展与突破。让我们来探讨一下定义 2024 年的一些关键趋势&…

WPF+MVVM案例实战与特效(三十八)- 封装一个自定义的数字滚动显示控件

文章目录 1、运行效果2、案例实现1、功能设计2、页面布局3、控件使用4、运行效果3、拓展:多数字自定义控件1、控件应用4、总结1、运行效果 在Windows Presentation Foundation (WPF)应用程序中,自定义控件允许开发者创建具有特定功能和外观的独特UI元素。本博客将介绍一个名…

ElasticSearch的自动补全功能(拼音分词器、自定义分词器、DSL实现自动补全查询、RestAPI实现自动补全查询)

文章目录 1. 什么是自动补全2. 拼音分词器2.1 初识拼音分词器2.2 下载拼音分词器2.3 安装拼音分词器2.4 测试拼音分词器 3. 自定义分词器3.1 拼音分词器存在的问题3.2 分词器&#xff08;analyzer&#xff09;的组成3.3 如何自定义分词器3.4 拼音分词器的可选参数3.5 配置自定义…

八股—Java基础(二)

目录 一. 面向对象 1. 面向对象和面向过程的区别&#xff1f; 2. 面向对象三大特性 3. Java语言是如何实现多态的&#xff1f; 4. 重载&#xff08;Overload&#xff09;和重写&#xff08;Override&#xff09;的区别是什么&#xff1f; 5. 重载的方法能否根据返回值类…

Java-08

类的抽象是将类的实现和使用分离, 而类的封装是将实现的细节封装起来并且对用户隐藏,用户只需会用就行。 类的合约指的是从类外可以访问的方法和数据域的集合以及与其这些成员如何行为的描述 isAlive()方法的返回值类型为布尔型&#xff08;Boolean&#xff09;。这个方法用于…

【MATLAB第109期】基于MATLAB的带置信区间的RSA区域敏感性分析方法,无目标函数

【MATLAB第108期】基于MATLAB的带置信区间的RSA区域敏感性分析方法&#xff0c;无目标函数 参考第64期文章【MATLAB第64期】【保姆级教程】基于MATLAB的SOBOL全局敏感性分析模型运用&#xff08;含无目标函数&#xff0c;考虑代理模型&#xff09; 创新点&#xff1a; 1、采…

机器视觉与OpenCV--01篇

计算机眼中的图像 像素 像素是图像的基本单位&#xff0c;每个像素存储着图像的颜色、亮度或者其他特征&#xff0c;一张图片就是由若干个像素组成的。 RGB 在计算机中&#xff0c;RGB三种颜色被称为RGB三通道&#xff0c;且每个通道的取值都是0到255之间。 计算机中图像的…

[数据结构#2] 图(1) | 概念 | 邻接矩阵 | 邻接表 | 模拟

图是由顶点集合及顶点间的关系&#xff08;边&#xff09;组成的数据结构&#xff0c;可用 G ( V , E ) G(V,E) G(V,E)表示&#xff0c;其中&#xff1a; 顶点集合 V V V: V { x ∣ x ∈ 某数据对象集 } V\{x|x\in\text{某数据对象集}\} V{x∣x∈某数据对象集}&#xff0c;…

自动驾驶---小米汽车智驾进展

1 背景 小米汽车的进度&#xff0c;可能出乎很多人的意料&#xff0c;其它新势力车企花了5---10年的时间&#xff0c;小米汽车三年就成功造出了第一辆车&#xff0c;在小米su7月销2万的同时&#xff0c;获得了非常不错的口碑。笔者在之前的博客《微自传系列---雷军》中已经阐述…

IOTIQS100芯片, TCP 发送数据+NSOSD,data要是hex16进制转换方法

命令&#xff1a;data以十六进制字符串格式发送的数据。 方法 代码 sprintf(temp, "%02X", data[i]);&#xff1a;将当前字节转换为两位宽的大写十六进制字符&#xff0c;并存储在 temp 中。如果需要小写字母&#xff0c;可以将格式说明符改为 "%02x"。 …

3.metagpt中的软件公司智能体 (Architect 角色)

目录 基础流程1. WriteDesign 动作类2. Architect 角色类3. 流程说明&#xff1a;4. Mermaid图&#xff1a;总结&#xff1a; 代码1. WriteDesign类2. Architect角色3. 上下文&#xff0c;即数据结构4. 数据准备4. 初次编写5. 重写 基础流程 用于管理软件开发任务的系统的一部…