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

🚀 作者主页: 有来技术

🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot

🌺 仓库主页: Gitee 💫 Github 💫 GitCode

💖 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请纠正!

目录

前言

处理多数据库场景是一项常见的任务。本文将介绍如何使用 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

    xml 复制代码
    <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

    xml 复制代码
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
      <version>4.2.0</version>
    </dependency>

动态数据源配置

yml 复制代码
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可以为组名也可以为具体某个库的名称
java 复制代码
/**
 * 主库查询
 */
@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);

单元测试类

java 复制代码
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 方法,以便将数据源上下文清空,避免影响后续的数据库操作。

java 复制代码
    /**
     * 测试手动方式切换数据源
     */
    @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 微服务商城
Github Gitee
后端 youlai-mall 🍃 youlai-mall 🍃
前端 mall-admin🌺 mall-admin 🌺
移动端 mall-app 🍌 mall-app 🍌
  • SpringBoot 3+ Vue3 单体权限管理系统
Github Gitee
后端 youlai-boot 🍃 youlai-boot 🍃
前端 vue3-element-admin 🌺 vue3-element-admin 🌺
相关推荐
鬼火儿14 小时前
SpringBoot】Spring Boot 项目的打包配置
java·后端
cr7xin14 小时前
缓存三大问题及解决方案
redis·后端·缓存
摇滚侠15 小时前
Spring Boot3零基础教程,Spring Boot 应用打包成 exe 可执行文件,笔记91 笔记92 笔记93
linux·spring boot·笔记
间彧15 小时前
Kubernetes的Pod与Docker Compose中的服务在概念上有何异同?
后端
间彧15 小时前
从开发到生产,如何将Docker Compose项目平滑迁移到Kubernetes?
后端
间彧15 小时前
如何结合CI/CD流水线自动选择正确的Docker Compose配置?
后端
间彧15 小时前
在多环境(开发、测试、生产)下,如何管理不同的Docker Compose配置?
后端
间彧15 小时前
如何为Docker Compose中的服务配置健康检查,确保服务真正可用?
后端
间彧15 小时前
Docker Compose和Kubernetes在编排服务时有哪些核心区别?
后端
间彧15 小时前
如何在实际项目中集成Arthas Tunnel Server实现Kubernetes集群的远程诊断?
后端