Spring Boot 和 MyBatis 环境下实现动态数据源切换
使用 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: masterdatasource:# 主库配置 (Key: master)master:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db_master?serverTimezone=Asia/Shanghaiusername: rootpassword: 123# 从库配置 (Key: slave)slave:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db_slave?serverTimezone=Asia/Shanghaiusername: rootpassword: 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 配置的数据源,即 masterpublic 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-groupdatasource:# 定义一个名为 master-group 的组,它包含一个主库和两个从库master-group:# 主库master:url: ...# 从库 1slave1:url: ...# 从库 2slave2: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 动态数据源问题的最佳实践。