SpringBoot和MyBatis环境下实现动态数据源切换过程
投稿:jingxian
dynamic-datasource-spring-boot-starter 是一个用于在SpringBoot和MyBatis环境下实现动态数据源切换的工具,它简化了配置和切换逻辑,通过引入依赖,配置数据源和使用@DS注解,可以轻松实现数据源的动态切换
使用 dynamic-datasource-spring-boot-starter
是在 Spring Boot 和 MyBatis 环境下实现动态数据源切换最简单和高效的方式。
这个 Starter 极大地简化了配置和切换逻辑,它自身集成了 AbstractRoutingDataSource
的所有逻辑。
使用dynamic-datasource-spring-boot-starter
1. 引入依赖
在您的 Maven 或 Gradle 项目中引入 Starter 依赖。
Maven:
<dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.5.2</version> </dependency>
2. 配置文件(application.yml或application.properties)
您只需在配置文件中定义所有的数据源。Starter 会自动将它们注册和管理起来。
它约定:
spring.datasource.dynamic.primary
:指定默认使用的数据源名称(Key)。spring.datasource.dynamic.datasource
:在下面配置您的具体数据源。
application.yml
示例:
spring: # 动态数据源配置 datasource: dynamic: # 默认数据源,未指定时将使用这个 primary: master datasource: # 主库配置 (Key: master) master: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db_master?serverTimezone=Asia/Shanghai username: root password: 123 # 从库配置 (Key: slave) slave: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db_slave?serverTimezone=Asia/Shanghai username: root password: 123
3. 实现数据源动态切换
Starter 提供了 @DS
注解来实现数据源的动态切换。这个注解可以直接用于 Service 层的方法、Mapper 接口的方法,甚至整个 Mapper 类上。
示例 1: 在 Service 层方法上切换
这是最常见的用法,因为 Service 层更贴近业务逻辑。
import com.baomidou.dynamic.datasource.annotation.DS; import org.springframework.stereotype.Service; @Service public class UserService { // 默认使用 primary 配置的数据源,即 master public User getMasterUser(Long id) { // ... 逻辑 } // 明确指定使用 slave 数据源,常用于查询 @DS("slave") public List<User> getSlaveUsers() { // ... 逻辑,此方法执行期间会使用 slave 库 return userMapper.selectAll(); } // 明确指定使用 master 数据源,常用于事务性的更新操作 @DS("master") public void updateMasterUser(User user) { // ... 逻辑,此方法执行期间会使用 master 库 userMapper.update(user); } }
示例 2: 在 Mapper 接口或方法上切换
您也可以直接在 Mapper 接口上指定数据源,但通常不推荐将数据源的决策放在持久层。
import com.baomidou.dynamic.datasource.annotation.DS; import org.apache.ibatis.annotations.Mapper; // 整个 Mapper 接口都使用 slave 数据源 @DS("slave") @Mapper public interface SlaveUserMapper { List<User> selectAll(); // 如果某个方法需要覆盖类上的配置,可以再次使用 @DS @DS("master") User selectById(Long id); }
额外高级功能
dynamic-datasource-spring-boot-starter
除了基础的动态切换外,还提供了一些非常实用的高级功能:
1. 读写分离(Load Balance)
该 Starter 原生支持基于组的负载均衡。
配置示例:
spring: datasource: dynamic: primary: master-group # 默认使用 master-group datasource: # 定义一个名为 master-group 的组,它包含一个主库和两个从库 master-group: # 主库 master: url: ... # 从库 1 slave1: url: ... # 从库 2 slave2: url: ...
使用方式:
- 写入操作(默认): 当您使用
@DS("master-group")
进行 写操作(UPDATE/INSERT/DELETE) 时,会自动连接到组内的master
库。 - 读取操作(负载均衡): 当您使用
@DS("master-group")
进行 读操作(SELECT) 时,会在slave1
和slave2
之间进行负载均衡(默认是轮询)。
2. 运行时添加/删除数据源
该 Starter 提供了 DynamicDataSourceService
接口,允许您在项目运行期间,通过代码动态地添加或删除数据源,这对于多租户等场景非常有用。
@Autowired private DynamicDataSourceCreator dynamicDataSourceCreator; @Autowired private DynamicDataSource dynamicDataSource; public void addTenantDataSource(String tenantId, DataSourceProperty dp) { // 1. 创建新的数据源(例如使用 Druid 或 Hikari 配置) DataSource newDs = dynamicDataSourceCreator.createDataSource(dp); // 2. 将数据源添加到动态数据源管理器中 dynamicDataSource.addDataSource(tenantId, newDs); }
总之
使用 @DS
注解和简洁的配置,dynamic-datasource-spring-boot-starter
是解决 MyBatis 动态数据源问题的最佳实践。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。