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 #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          url: jdbc:mysql://192.168.183.128:3306/user
          username: root
          password: 123456
        slave_1:
          url: jdbc:mysql://192.168.183.128:3307/user
          username: root
          password: 123456
        slave_2:
          url: jdbc:mysql://192.168.183.128:3308/user
          username: root
          password: 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 {

  @Autowired
  private UserMapper userMapper;

  @Override
  public 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。

今天的分享就到这里。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Crawl4AI:一个为大型语言模型(LLM)和AI应用设计的网页爬虫和数据提取工具实战

这里写目录标题 一、crawl4AI功能及简介1、简介2、特性 二、项目地址三、环境安装四、大模型申请五、代码示例1.生成markdown2.结构化数据 一、crawl4AI功能及简介 1、简介 Crawl4AI 是一个开源的网页爬虫和数据抓取工具&#xff0c;一个python项目&#xff0c;主要为大型语言…

【银河麒麟高级服务器操作系统】有关dd及cp测试差异的现象分析详解

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn dd现象 使用银河麒麟高级服务器操作系统执行两次…

sqli-labs靶场第26-30关

第26关 这关将逻辑运算符&#xff0c;注释符以及空格给过滤了 我们先使用单引号进行闭合 这时我们查看源代码可以看到这一关过滤了很多字符 可以看到这里将or and / -- # 空格等字符都被注释了 空格被过滤了我们可以使用()来代替&#xff0c;and和or可以使用双写来绕过 因为…

ik分词器了解 和 通过zip安装包的方式 将ik分词器安装到elasticsearch中

目录 1. ik分词器的作用&#xff08;效果&#xff09; &#xff08;1&#xff09;标准分析器效果 &#xff08;2&#xff09;ik_smart分词 &#xff08;3&#xff09;ik_max_word分词 2. 首先根据自己的elasticsearch的版本下载对应的ik分词器版本 3. 将下载好的ik分词器…

实景视频与模型叠加融合?

[视频GIS系列]无人机视频与与实景模型进行实时融合_无人机视频融合-CSDN博客文章浏览阅读1.5k次&#xff0c;点赞28次&#xff0c;收藏14次。将无人机视频与实景模型进行实时融合是一个涉及多个技术领域的复杂过程&#xff0c;主要包括无人机视频采集、实景模型构建、视频与模型…

【解决】k8s使用kubeadm初始化集群失败问题整理

执行提示命令&#xff0c;查看报错信息 journalctl -xeu kubelet1、错误&#xff1a;running with swap on is no 报错 "command failed" err"failed to run Kubelet: running with swap on is no 解决&#xff1a; swap未禁用&#xff0c;需要禁用swap&…

aws(学习笔记第十七课) SQS Amazon Simple Queue Service服务

aws(学习笔记第十七课) SQS Amazon Simple Queue Service服务 学习内容&#xff1a; 使用SQS Amazon Simple Queue Service服务整体代码&#xff08;nodejs的通常工程&#xff09;代码动作 1. 使用SQS Amazon Simple Queue Service服务 利用应用程序来学习SQS 创建S3$ aws s…

qt-C++笔记之父类窗口、父类控件、对象树的关系

qt-C笔记之父类窗口、父类控件、对象树的关系 code review! 参考笔记 1.qt-C笔记之父类窗口、父类控件、对象树的关系 2.qt-C笔记之继承自 QWidget和继承自QObject 并通过 getWidget() 显示窗口或控件时的区别和原理 3.qt-C笔记之自定义类继承自 QObject 与 QWidget 及开发方式…

VMware ubuntu12.04怎么设置静态IP联网

记得刚开始学习嵌入式就是从ubuntu12.04的环境开始学习的C语言&#xff0c;当时没有弄清楚怎么设置静态IP联网&#xff0c;现在写一篇文章。 1.首先&#xff0c;关闭ubuntu的网络&#xff1b; 2.电脑使用的是wifi,将VMware桥接到该网卡上&#xff1b; 3.在虚拟机设置里面选择桥…

计算机视觉中的图像滤波与增强算法

摘要&#xff1a; 本文深入探讨了计算机视觉领域中的图像滤波与增强算法。首先介绍了图像滤波与增强的基本概念和重要性&#xff0c;随后详细阐述了线性滤波算法中的均值滤波和高斯滤波&#xff0c;以及非线性滤波算法中的中值滤波和双边滤波&#xff0c;包括它们的原理、数学模…

AI大模型学习笔记|神经网络与注意力机制(逐行解读)

来源分享链接&#xff1a;通过网盘分享的文件&#xff1a;详解神经网络是如何训练的 链接: https://pan.baidu.com/s/12EF7y0vJfH5x6X-0QEVezg 提取码: k924 内容摘要&#xff1a;本文深入探讨了神经网络与注意力机制的基础&#xff0c;以及神经网络参数训练的过程。以鸢尾花数…

腾讯云系统盘扩容

在腾讯云申请空间后&#xff0c;只要执行三行命令 云硬盘 在线扩展系统盘分区及文件系统-操作指南-文档中心-腾讯云 安装工具 yum install -y cloud-utils-growpart 给/eav/vda1扩分区 LC_ALLen_US.UTF-8 growpart /dev/vda 1 挂载扩容 ext4 文件系统 resize2fs /dev/vda1 …

【控制系统】深入理解反步控制(Backstepping) | 反步法控制器原理与应用实例解析(附Matlab/Simulink仿真实现)

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

构建树莓派温湿度监测系统:从硬件到软件的完整指南

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

人工智能系统

介绍人工智能 的基础书 点击这里 1.1 深度学习的历史&#xff0c;现状与发展 本章将介绍深度学习的由来&#xff0c;现状和趋势&#xff0c;让读者能够了解人工智能系统之上的深度学习负载的由来与趋势&#xff0c;为后面理解深度学习系统的设计和权衡形成初步的基础。我们在后…

NVR小程序接入平台EasyNVR设置预置位显示“参数错误”的解决方法

视频监控技术在现代社会中的应用已经变得越来越广泛&#xff0c;从城市安防到家庭安全&#xff0c;从交通管理到商业监控&#xff0c;其作用无处不在。随着科技的不断进步&#xff0c;视频监控不仅提高了安全性&#xff0c;还带来了许多新的机遇和挑战。 近期&#xff0c;我们收…

下载红米Note 9 Pro5G对应的LineageOS代码下载及编译

构建 LineageOS 进入网站&#xff1a;Info about gauguin | LineageOS Wiki&#xff0c;点击&#xff1a;Build for yourself&#xff0c;里面有详细的教程&#xff0c;我这里就按照Note 9 Pro 5G来。 机器环境 Ubuntu环境为&#xff1a;20.04.6LinagesOS版本&#xff1a;21-…

如何在 Ubuntu 22.04 上安装 Strapi CMS

简介 Strapi 是一个使用 JavaScript 构建的开源、无头内容管理系统 (CMS)。与其他无头 CMS 一样&#xff0c;Strapi 开箱即用不带前端。它使用 API 作为其前端&#xff0c;允许你使用流行的框架&#xff08;如 React 和 Next.js&#xff09;构建网站。Strapi 基于插件系统&…

Java:集合(List、Map、Set)

文章目录 1. Collection集合1-1. 迭代器遍历方式1-2. 通过for循环进行遍历1-3. forEach遍历 2. List集合2-1. ArrayList底层实现原理2-2. LinkedList底层实现原理 3. Set集合3-1. HashSet 底层实现3-2. LinkedHashSet 底层实现3-3. TreeSet 4. Collection集合->总结5. Map集…

私有云dbPaaS为何被Gartner技术成熟度曲线标记为“废弃”?

当云计算席卷而来&#xff0c;基于云基础设施的数据库部署也改变了数据库。在传统的私有化部署&#xff08;On-premises&#xff09;和公有云部署&#xff08;Public Cloud&#xff09;之间&#xff0c;不断融合的混合IT&#xff08;Mixed IT&#xff09;形式成为最常见的企业级…