前言
日常开发中,可能会遇到一个项目要调用多个数据源的情况,比如同一个 MySQL 不同的库,也可能是从不同的 MySQL 进行获取数据,此时,我们可以使用 dynamic datasource
进行多数据源切换。
dynamic datasource 介绍
dynamic datasource
其实是 苞米豆(也就是 MyBatis-Plus)的其中一个框架,是一个基于 Spring Boot 的快速集成多数据源的启动器。
更详细的了解,请前往 dynamic datasource 官网
快速开始
演示环境
- IntelliJ IDEA 2020.3.2
- JDK 8
- MySQL 5.7
- Maven 3.6.3
- Spring Boot 2.4.5
SQL 准备(创建了两个库,分别是 dep
和 emp
)
dep
库下的表
1 2 3 4 5 6 7 8 9 10 11 12
| CREATE TABLE `t_dep` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
INSERT INTO `t_dep` VALUES ('1', '開發部'); INSERT INTO `t_dep` VALUES ('2', '測試部'); INSERT INTO `t_dep` VALUES ('3', '生產部');
|
emp
库下的表
1 2 3 4 5 6 7 8 9 10 11 12
| CREATE TABLE `t_emp` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
INSERT INTO `t_emp` VALUES ('1', '張三'); INSERT INTO `t_emp` VALUES ('2', '李四'); INSERT INTO `t_emp` VALUES ('3', '王五');
|
然后创建 Spring Boot 项目,引入基本的 Web 依赖和 MySQL 驱动
完整的 pom
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.1.0</version> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency>
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
|
编写配置文件(application.yaml
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| spring: datasource: dynamic: primary: master strict: false datasource: master: url: jdbc:mysql:///dep username: garvey password: root driver-class-name: com.mysql.jdbc.Driver slave: url: jdbc:mysql:///emp username: garvey password: root driver-class-name: com.mysql.jdbc.Driver
|
dao
层(因为就这么一句简单 SQL,这里就不创建 mapper 映射文件了,直接使用注解)
1 2 3 4 5 6 7 8 9 10 11
| public interface DepMapper {
@Select("SELECT id, name FROM t_dep") List<Dep> selectAll(); }
public interface EmpMapper {
@Select("SELECT id, name FROM t_emp") List<Emp> selectAll(); }
|
实体类就没什么好讲的了
然后就可以通过 @DS
注解进行切换数据源。
@DS
注解可以作用在方法上也可以作用在类上,同时存在就近原则,方法上的注解优先于类上的注解。
注解 | 结果 |
---|
没有 @DS | 默认数据源 |
@DS(“dsName”) | dsName 可以为组名也可以为具体某个库的名称 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Service @DS("master") public class TestService {
@Autowired private DepMapper depMapper;
@Autowired private EmpMapper empMapper;
public List<Dep> selectDepAll() { return depMapper.selectAll(); }
@DS("slave") public List<Emp> selectEmpAll() { return empMapper.selectAll(); } }
|
在启动类中加上扫描 Mapper 接口的注解,最后创建 Controller
进行测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @RestController public class TestController {
@Autowired private TestService testService;
@GetMapping("dep") public Object dep() { return testService.selectDepAll(); }
@GetMapping("emp") public Object emp() { return testService.selectEmpAll(); } }
|
启动之后,打开浏览器分别访问
http://localhost:8080/dep
http://localhost:8080/emp
参考文档