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 动态数据源问题的最佳实践。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
