Spring Boot 3 整合 Mybatis-Plus 实现动态数据源切换实战

news2024/11/19 3:26:21

🚀 作者主页: 有来技术
🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot
🌺 仓库主页: Gitee 💫 Github 💫 GitCode
💖 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请纠正!

目录

  • 前言
  • Spring Boot 整合动态数据源
    • Maven 依赖
    • 动态数据源配置
  • 动态切换数据源实战
    • 注解切换数据源
    • 手动切换数据源
  • 动态数据源原理
  • 结语
  • 开源项目

前言

处理多数据库场景是一项常见的任务。本文将介绍如何使用 dynamic-datasource-spring-boot-starter 启动器,以简化 Spring Boot 项目中的多数据源集成。

Spring Boot 整合动态数据源

参考 dynamic-datasource 官网:https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611

Maven 依赖

pom.xml 添加依赖坐标,Spring Boot 3 区别其他版本,使用的是 dynamic-datasource-spring-boot3-starter , 其他版本的 Spring Boot 使用 dynamic-datasource-spring-boot-starter , 除了依赖区别,其他配置和使用方式新老版本无差别。

  • Spring Boot 3

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
        <version>4.2.0</version>
    </dependency>
    
  • Spring 1.5.x Spring 2.x.x

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

动态数据源配置

spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为 master
      strict: false # 设置严格模式,当数据源找不到时,是否抛出异常,默认为false不抛出
      datasource:
        master: # 主库
          type: com.alibaba.druid.pool.DruidDataSource
          driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
          url: jdbc:mysql://www.youlai.tech:3306/youlai_boot?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true
          username: youlai
          password: 123456
        slave: # 从库
          type: com.alibaba.druid.pool.DruidDataSource
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/youlai_boot?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true
          username: root
          password: 123456

动态切换数据源实战

注解切换数据源

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

注解结果
没有@DS默认数据源
@DS(“dsName”)dsName可以为组名也可以为具体某个库的名称
/**
 * 主库查询
 */
@DS("master")
@Select("select * from sys_user where id = #{userId}")
SysUser getUserFromMaster(Long userId);

/**
 * 从库查询
 */
@DS("slave")
@Select("select * from sys_user where id = #{userId}")
SysUser getUserFromSlave(Long userId);

单元测试类

package com.youlai.system.mapper;

import com.youlai.system.model.entity.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
@Slf4j
class SysUserMapperTest {

    @Autowired
    private SysUserMapper userMapper;

    private final Long userId = 1L;

    /**
     * 测试注解方式切换数据源
     */
    @Test
    void testSwitchDataSourceByAnnotation() {
        SysUser masterUser = userMapper.getUserFromMaster(userId);
        log.info("用户ID:{} 主库姓名:{}", userId, masterUser.getNickname());
        SysUser slaveUser = userMapper.getUserFromSlave(userId);
        log.info("用户ID:{} 从库姓名:{}", userId, slaveUser.getNickname());
    }
}

测试结果

手动切换数据源

有些场景没法使用注解去切换,举个例子,同一个方法内使用 Mybatis-Plus 提供的方法先后分别从主库和从库各查一次。

这时候简单的切换数据源就是使用 DynamicDataSourceContextHolder 的 push 方法动态设置数据源上下文,完成了使用特定数据源的数据库操作后,再调用 poll 方法,以便将数据源上下文清空,避免影响后续的数据库操作。

    /**
     * 测试手动方式切换数据源
     */
    @Test
    void testDataSourceSwitchManually() {
        DynamicDataSourceContextHolder.push("master");
        SysUser masterUser = userMapper.selectById(userId);
        log.info("手动切换:主库姓名:{}", masterUser.getNickname());
        DynamicDataSourceContextHolder.poll();

        DynamicDataSourceContextHolder.push("slave");
        SysUser slaveUser = userMapper.selectById(userId);
        log.info("手动切换:从库姓名:{}",  slaveUser.getNickname());
        DynamicDataSourceContextHolder.poll();
    }

测试结果

动态数据源原理

源码图如下,原理会在下一篇【原理篇】详细讲解。
在这里插入图片描述

结语

通过 dynamic-datasource-spring-boot-starter 这个启动器,我们轻松实现了在 Spring Boot 项目中集成多数据源的功能。无论是注解方式还是手动方式切换数据源,都使得处理多数据库场景变得更加简便和灵活。

在注解方式中,通过 @DS 注解,我们可以轻松切换数据源,实现了一定的自动化。而在手动方式中,使用 DynamicDataSourceContextHolderpushpoll 方法,我们可以更加灵活地控制数据源的切换,适用于一些特殊场景。

在下一篇文章中,我们将深入探讨 dynamic-datasource 的原理,了解其如何实现动态数据源切换,同时也会对 MyBatis 的源码进行一些了解。这将有助于更好地理解多数据源切换的底层机制。

开源项目

  • SpringCloud + Vue3 微服务商城
GithubGitee
后端youlai-mall 🍃youlai-mall 🍃
前端mall-admin🌺mall-admin 🌺
移动端mall-app 🍌mall-app 🍌
  • SpringBoot 3+ Vue3 单体权限管理系统
GithubGitee
后端youlai-boot 🍃youlai-boot 🍃
前端vue3-element-admin 🌺vue3-element-admin 🌺

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

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

相关文章

银河麒麟本地软件源配置方法

软件源介绍 软件源可以理解为软件仓库&#xff0c;当需要安装软件时则会根据源配置去相应的软件源下载软件包&#xff0c;此方法的优点是可以自动解决软件包的依赖关系。常见的软件源有光盘源、硬盘源、FTP源、HTTP源&#xff0c;本文档主要介绍本地软件源的配置方法&#xff…

专注抖音短视频账号矩阵系统源头开发---saas工具

抖音账号|短视频矩阵分发系统 | 多账号管理发布 |MVC架 短视频矩阵分发系统是一种可以帮助企业、机构和个人高效分发短视频的工具。随着社交媒体的不断普及&#xff0c;短视频的使用越来越广泛&#xff0c;因此如何快速而准确地将短视频传播到不同的平台和账号上已经成为了一个…

短剧分销平台搭建:短剧变现新模式

短剧作为今年大热的行业&#xff0c;深受大众追捧&#xff01;短剧剧情紧凑&#xff0c;几乎每一集都有高潮剧情&#xff0c;精准击中了当下网友的碎片化时间。 短剧的形式较为灵活&#xff0c;可以轻松融入各种的元素&#xff0c;比如喜剧、悬疑、爱情等&#xff0c;可以满足…

一加 12 Pop-up快闪活动来袭,十城联动火爆开启

12 月 9 日&#xff0c;一加 12 Pop-up 快闪活动在北京、深圳、上海、广州等十城联动开启&#xff0c;各地加油欢聚快闪现场&#xff0c;抢先体验与购买一加 12。作为一加十年超越之作&#xff0c;一加 12 全球首发拥有医疗级护眼方案和行业第一 4500nit 峰值亮度的 2K 东方屏、…

postman常用脚本

一、在参数中动态添加开始时间和结束时间的时间戳 1.先在collection中添加参数&#xff0c;这里的作用域是collection&#xff0c;也可以是其他的任何scope 2.在Pre-request Script 中设定开始时间和结束时间参数&#xff0c;比如昨天和今天的时间戳&#xff0c;下面是js代码 …

彻底搞懂零拷贝技术( DMA、PageCache)

DMA 直接内存访问&#xff08;Direct Memory Access&#xff09; 什么是DMA&#xff1f; 在进行数据传输的时候&#xff0c;数据搬运的工作全部交给 DMA 控制器&#xff0c;而 CPU 不再参与&#xff0c;可以去干别的事情。 传统I/O 在没有 DMA 技术前&#xff0c;全程数据…

【图论笔记】克鲁斯卡尔算法(Kruskal)求最小生成树

【图论笔记】克鲁斯卡尔算法&#xff08;Kruskal&#xff09;求最小生成树 适用于 克鲁斯卡尔适合用来求边比较稀疏的图的最小生成树 简记&#xff1a; 将边按照升序排序&#xff0c;选取n-1条边&#xff0c;连通n个顶点。 添加一条边的时候&#xff0c;如何判断能不能添加…

链表OJ—相交链表

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 1、相交链表的题目&#xff1a; 方法讲解&#xff1a; 图文解析&#xff1a; 代码实现&#xff1a; 总结 前言 世上有两种耀眼的光芒&#xff0c;一种是正在升…

《PySpark大数据分析实战》图书上线啦

《PySpark大数据分析实战》图书上线啦 《PySpark大数据分析实战》图书上线啦特殊的日子关于创作关于数据关于Spark关于PySpark关于图书/专栏 《PySpark大数据分析实战》图书上线啦 特殊的日子 不知不觉一转眼入驻CSDN已经满一年了&#xff0c;这真是一个充满意义的特殊的日子&…

SystemUI下拉通知菜单栏定时自动隐藏

前言 在系统应用开发过程中&#xff0c;常常遇到一些特殊的需求&#xff0c;Android原生的应用并无此适配&#xff0c;此时需要对系统应用进行定制化开发。 目前遇到的这样一个需求&#xff1a;下拉通知菜单栏时&#xff0c;定时8秒后自动关闭通知菜单栏。通知菜单栏为Sytstem…

如何用Python编写俄罗斯方块Tetris游戏?

在本文中&#xff0c;我们将用Python代码构建一个令人惊叹的项目&#xff1a;俄罗斯方块游戏。在这个项目中&#xff0c;我们将使用pygame库来构建游戏。要创建此项目&#xff0c;请确保您的系统中安装了最新版本的Python。让我们开始吧&#xff01; Pygame是一组跨平台的Pyth…

Mysql研学-认识与安装

一 数据库 1 Java的数据存储技术 ① 变量:一个数据存储空间的表示 ② 数组:存储一组相同数据类型的"容器" ③ 集合:存储一组任意引用数据类型的"容器" ④ 配置文件: .properties:基于Properties集合存储(Map集合的具体实例) .xml文件:基于标签存储数据…

centos7 安装 mysql8 详细步骤记录

下载 mysql 8 更新系统&#xff1a; sudo yum update 添加 MySQL Yum存储库&#xff1a; sudo rpm -Uvh https://repo.mysql.com/mysql80-community-release-el7-3.noarch.rpm 安装 MySQL 8&#xff1a; sudo yum install mysql-server 重置密码 查看初始密码&#xff1…

三种入耳检测光感芯片驱动开发比较

三种入耳检测光感芯片驱动开发比较 是否需要申请加入数字音频系统研究开发交流答疑群(课题组)&#xff1f;可加我微信hezkz17, 本群提供音频技术答疑服务&#xff0c;群赠送语音信号处理降噪算法&#xff0c;蓝牙耳机音频&#xff0c;DSP音频项目核心开发资料, 重要的寄存器…

应用层之应用层的网络应用模型————C/S和P2P、域名解析系统DNS、文件传输协议FTP

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

Ubuntu上svn基本使用(gitee提交下载)

目录 环境准备 1. 获取代码到本地 直接获取 获取代码时加入用户名密码 指定版本更新 2. 提交代码 3. 展示代码列表 4. 添加代码文件(目录) 5. 删除gitee仓库中的文件 参考文档链接 环境准备 当前操作系统为Ubuntu22.04LTS gitee 创建仓库时 需要打开svn的支持 sudo…

54.grpc实现文件上传和下载

文章目录 一&#xff1a;简介1. 什么是grpc2. 为什么我们要用grpc 二&#xff1a;grpc的hello world1、 定义hello.proto文件2、生成xxx_grpc.pb.go文件3、生成xxx.pb.go结构体文件4、编写服务代码service.go5、编写客户端代码client.go 三、服务端流式传输&#xff1a;文件下载…

短视频无人实景直播源码技术开发=抖去推saas直播源码

开发无人直播源码技术需要具备一定的编程和网络知识。以下是一些基本的步骤和资源&#xff0c;帮助你进行无人直播源码的开发搭建&#xff1a; 1. 选择编程语言和开发环境&#xff1a;根据你的个人喜好和技术熟练程度&#xff0c;可以选择一些流行的编程语言&#xff0c;如Pyth…

根据应聘者的姓名和所学专业判断是否需要这样的程序设计人员

一、程序分析 导入Scanner函数&#xff0c;分别输入应聘者的姓名和应聘者所学的程序设计语言。 二、具体代码 import java.util.Scanner; public class Recruitment {public static void main(String[] args){try (Scanner scan new Scanner(System.in)) {System.out.prin…

【Vue】设置路由默认跳转指定页面

目录 设置路由默认跳转 上一篇&#xff1a; 登录注册界面制作 https://blog.csdn.net/m0_67930426/article/details/134895214?spm1001.2014.3001.5502 以这篇文章为例 首先我们要了解一下vue项目的router包的作用 上一篇文章里&#xff0c;创建了登录注册页面 如果我们…