前言
处理多数据库场景是一项常见的任务。本文将介绍如何使用 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 注解,我们可以轻松切换数据源,实现了一定的自动化。而在手动方式中,使用 DynamicDataSourceContextHolder 的 push 和 poll 方法,我们可以更加灵活地控制数据源的切换,适用于一些特殊场景。
在下一篇文章中,我们将深入探讨 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🌺 |