Spring进阶:3步引入MybatisPlus多数据源,详细配置及原理解析

news2024/9/9 7:58:44

前言

MybatisPlus(MP)作为mybatis的增强工具,提供了配置多数据源的扩展,通过简单的几步配置,即可使用注解轻松切换数据源。

以下是dynamic-datasource提供的功能列表:

使用方法

1,引入dynamic-datasource-spring-boot-starter。

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

2,配置多数据源。

spring:
  datasource:
    dynamic:
      primary: master #默认主库名为master
      strict: false #不使用严格模式
      datasource:
        master:
          url: jdbc:mysql://127.0.0.1:3306/master
          username: root
          password: 66668888
          driver-class-name: com.mysql.jdbc.Driver 
        slave_1:
          url: jdbc:mysql://127.0.0.1:3307/slave_1
          username: root
          password: 66668888
          driver-class-name: com.mysql.jdbc.Driver
        slave_2:
          url: ENC(xxxxx) # 内置加密
          username: ENC(xxxxx)
          password: ENC(xxxxx)
          driver-class-name: com.mysql.jdbc.Driver

主库默认为master,从库命名的格式默认以_分割。

3,在方法或者类上使用@DS切换数据源

DS注解既可以写在类上,也可以写在方法上,方法上的优先级高于类。

如果没有指定DS的属性值或者没有使用DS注解,就自动走master主库。

通过以上3步,就可以轻松使用MP切换多数据源的能力了。当然,除了支持主从模式,还支持多主多从、多库,混合模式。

原理探究

打开dynamic-datasource-spring-boot-starter.jar包,在spring.factories文件中,可以看到配置了DynamicDataSourceAutoConfiguration启动类。

打开DynamicDataSourceAutoConfiguration类,可以看到通过@AutoConfigureBefore注解,提前初始化了MP自己的DataSource数据源。

而DataSourceAutoConfiguration类的核心作用就是初始化DataSrouce,MP通过抢先配置的方式,使DataSource变成了自己指定的数据源。

除了初始化MP自己的数据源,DynamicDataSourceAutoConfiguration类还做了一些其他的初始化工作,比如DynamicDataSourceProperties配置,初始化DS注解的切面Advisor等。

初始化工作做完以后,接下来就是根据DS注解判断走哪个数据源了。

DynamicDataSourceAnnotationInterceptor类是一个方法拦截器,它的invoke里面有判断DS key的操作。

在determineDatasourceKey方法中,会调用提前注入的DataSourceClassResolver类的findKey方法,判断类或者方法上是否指定了DS注解。

在这个方法中,MP会将方法的判断结果缓存下来,下次执行相同的类方法就可以直接缓存,从而大大提升查找效率。

获取到dsKey以后,会将其设置在DynamicDataSourceContextHolder中的LOOKUP_KEY_HOLDER中,它是一个泛型为Deque的ThreadLocal,为什么设置成栈呢?官方给出的解释是:

接下来就是获取数据库链接的AbstractRoutingDataSource类的getConnection方法,

而determineDataSource方法就会去获取指定的数据源,

这里的逻辑是:如果没有指定DS,就走主库,如果指定了DS,就根据DS的属性值进行条件匹配,看走哪个判断分支。

获取到connection链接之后,接下来就是执行真正的数据库语句了。

以上就是一个常见的数据库操作的流程,大体思路就是先找MP的启动类,看看启动类都做了哪些工作,之后再按照找数据源,找链接的思路,看MP是如何具体实现多数据源切换的操作的。

当然,MP多数据源还有其他的功能点,但整体来说,代码逻辑并不是很复杂,大家可以通过debug对源码进行梳理。

写文不易,感谢您的点赞和关注。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第六章 数组、排序和查找

一、数组&#xff08;P156&#xff09; 1. 数组介绍 数组可以存放多个同一类型的数据。数组也是一种数据类型&#xff0c;是引用类型。即&#xff1a;数(数据)组(一组)就是一组数据2. 数组的使用 2.1 使用方式1&#xff1a;动态初始化 数组的定义&#xff1a;数据类型 …

uniCloud 微信小程序登陆全流程demo

ps&#xff1a; 博主一向不喜欢废话&#xff0c;直接说几个点&#xff0c;你悟了就直接去试&#xff0c;可以不用看完&#xff0c;还是得自己去试印象才深刻&#xff0c;博主写博文就怕自己以后忘记做个笔记顺便能帮一个是一个 1、你要获取unionid 肯定得访问外网&#xff0c;u…

【C++初阶】六、STL---string(总)|为什么学习string类|标准库中的string类|string 类常用接口

目录 一、为什么学习string类 1.1 C语言中的字符串 1.2 字符串在OJ面试中 二、标准库中的string类 2.1 string 介绍 2.2 编码格式 三、string 类常用接口 3.1 Member functions&#xff08;成员函数&#xff09; 3.1.1 构造函数&#xff08;Construct&#xff09; 3.…

C++11 并发指南七(C++11 内存模型一:介绍)

C11 并发指南七(C11 内存模型一&#xff1a;介绍) 文章目录C11 并发指南七(C11 内存模型一&#xff1a;介绍)第六章主要介绍了 C11 中的原子类型及其相关的API&#xff0c;原子类型的大多数 API 都需要程序员提供一个 std::memory_order&#xff08;可译为内存序&#xff0c;访…

面试第一次被问到SDK测试,当时就懵了

01、是什么 客户端SDK是为第三方开发者提供的软件开发工具包&#xff0c;包括SDK接口、开发文档和Demo示例等。SDK和应用之间是什么关系呢&#xff1f;以云信即时消息服务为例&#xff0c;如下图所示&#xff0c;应用客户端通过调用云信SDK接口&#xff0c;进行消息等数据查询…

[前端笔记——CSS] 14.图像、媒体和表单元素

[前端笔记——CSS] 14.图像、媒体和表单元素1.CSS调整大小2.图片、媒体和表单元素2.1替换元素2.2 form元素2.3 举个实例1.CSS调整大小 一个空的<div>是没有尺寸的。如果在 HTML 文件中添加一个空<div> 并给予其边框&#xff0c;则会在页面上看到一条线。 <div…

【软件安装】ubuntu安装nvidia驱动,解决闪屏问题

Official Drivers | NVIDIA nvidia驱动下载官网&#xff0c;登陆速度是有点慢的&#xff0c;需要耐心等待 我的电脑是笔记本&#xff0c;ubuntu18.04.6&#xff0c;NVIDIA GeForce RTX 3050 Laptop GPU 天时地利人和的情况下&#xff0c;按照下面这篇博文就可以顺利安装nvidi…

【存储】etcd的存储是如何实现的(2)

在上一篇中&#xff0c;介绍了etcd底层存储的内容&#xff0c;包括wal、raft.MemoryStorage以及backend。在介绍backend时提到了backend只是etcd kv存储的一部分&#xff0c;负责持久化存储&#xff0c;backend加内存化treeIndex才构成etcd完整的支持mvcc的kv存储。所以这篇就来…

红队大量资产指纹探测工具和摄像头漏-洞渗-透和利用工具

红队大量资产指纹探测工具和摄像头漏-洞渗-透和利用工具。 Finger定位于一款红队在大量的资产中存活探测与重点攻-击系统指纹探测工具。在面临大量资产时候Finger可以快速从中查找出重点攻-击系统协助我们快速展开渗-透。 实际效果 URL批量扫描效果如下: 调用api进行资产收集效…

第九层(6):STL之queue

文章目录前情回顾queue概念queue容器需要注意的地方queue类内的构造函数queue类内的赋值操作queue类内的插入操作queue类内的删除操作queue类内的访问queue类内的大小操作下一座石碑&#x1f389;welcome&#x1f389; ✒️博主介绍&#xff1a;一名大一的智能制造专业学生&…

设计模式第4式:观察者模式Spring事件监听机制

前言 观察者模式是一种非常重要的设计模式&#xff0c;在JDK和Spring源码中使用非常广泛&#xff0c;而且消息队列软件如kafka、rocketmq等也应用了观察者模式。那么我们就很有必要学习一下观察者模式了。 随后我们来看看大名鼎鼎的事件监听机制&#xff0c;它是基于观察者模…

直波导与微环的耦合——Lumerical仿真1

微环与直波导的耦合的Lumerical仿真的一个记录&#xff0c;包括仿真步骤和一些问题的探究&#xff0c;参考自https://www.bilibili.com/video/BV1tF411z714。 &#x1f381;附Lumerical仿真文件 Lumerical第一个仿真一、建立结构1、放置微环结构2、修改结构二、光源1、放置光源…

React是不是MVVM架构?

首先说结论&#xff1a;不是 一、MVVM Model-View-ViewModel&#xff1a;一句话概括MVVM&#xff0c;操作数据&#xff0c;就是操作视图&#xff0c;就是操作DOM。开发者只需要完成包含申明绑定的视图模板&#xff0c;编写ViewModel中业务数据变更逻辑&#xff0c;View层则完…

MySQL(六):redo日志——保证事务的持久性

目录一、redo日志的基本介绍1.1 什么是redo日志1.2 redo日志的格式1.3 redo日志的类型1.4 Mini-Transaction二、redo日志的写入过程2.1 redo log block2.2 redo日志缓冲区2.3 将redo日志写入log buffer2.3 redo日志刷新到磁盘2.5 redo日志文件组2.6 redo日志文件格式2.7 log se…

【MySQL进阶】MySQL触发器详解

序号系列文章7【MySQL基础】运算符及相关函数详解8【MySQL基础】MySQL多表操作详解9【MySQL进阶】MySQL事务详解10【MySQL进阶】MySQL视图详解文章目录前言1&#xff0c;触发器1.1&#xff0c;触发器概述1.2&#xff0c;触发器使用环境2&#xff0c;触发器基本操作2.1&#xff…

CentOS7 安装单机 Kafka

一、单机安装 1、上传压缩文件到服务器、解压 tar -zxvf kafka_2.13-3.3.2.tgz -C /usr/local #解压到 usr/local目录下 进入解压目录下 更名kafka mv kafka_2.13-3.3.2/ kafka-3.3.2 2、配置环境变量 vim /etc/profile export KAFKA_HOME/usr/local/kafka-3.3.2export PATH$PA…

MySQL学习记录(9)InnoDB存储引擎

文章目录6、InnoDB存储引擎6.1、逻辑存储结构6.2、架构6.2.1、概述6.2.2、内存结构6.2.3、磁盘结构6.2.4、后台线程6.3、事务原理6.3.1、事务基础6.3.2、redo log日志6.3.3、undo log日志6.4、MVCC6.4.1、基本概念6.4.2、记录中隐藏字段6.4.3、undo log日志6.4.4、readview6.4.…

【Pytorch项目实战】之图像分类与识别:手写数字识别(MNIST)、普适物体识别(CIFAR-10)

文章目录图像分类与识别&#xff08;一&#xff09;实战&#xff1a;基于CNN的手写数字识别&#xff08;数据集&#xff1a;MNIST&#xff09;&#xff08;二&#xff09;实战&#xff1a;基于CNN的图像分类&#xff08;数据集&#xff1a;CIFAR-10&#xff09;图像分类与识别 …

Lua 函数 - 可变参数

Lua 函数 - 可变参数 参考至菜鸟教程。 Lua函数可以接收可变数目的参数&#xff0c;和C语言类似&#xff0c;在函数参数列表中使用三点...表示函数有可变的参数。 function add(...) local s 0 for i, v in ipairs{...} do --> {...} 表示一个由所有变长参数构成的数…

模拟实现C库函数(2)

"烦恼无影踪,丢宇宙~"上一篇的模拟实现了好几个库函数,strlen\strcpy\memcpy\memmove,那么这一篇又会增加几个常用C库函数的模拟实现 memset\itoa\atoi。一、memsetmemset - fill memory with a constant byte#include <string.h>void *memset(void *s, int c,…