# MyBatis-Plus教程 - 17 多数据源配置

有时候我们的项目可能需要访问多个数据库,那就需要配置多个数据源。

下面就讲解一下 MyBatis-Plus 如何配置多个数据源。

# 17.1 配置实现

# 1 创建数据库

因为是配置多个数据源,为了测试,再创建一个数据库和表,让项目连接两个数据库。

# 建库
CREATE DATABASE IF NOT EXISTS foooor_db2 CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
USE foooor_db2;

# 建表
CREATE TABLE `tb_user` (
  `id` BIGINT(20) NOT NULL,
  `username` VARCHAR(32) NULL,
  `password` VARCHAR(32) NULL,
  `email` VARCHAR(64) NULL,
  `age` INT NULL,
  `create_time` DATETIME NULL,
  `update_time` DATETIME NULL,
  PRIMARY KEY (`id`)
) 
ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4;

# 准备数据:
INSERT INTO `tb_user` 
(`id`, `username`, `password`, `email`, `age`, `create_time`, `update_time`)
VALUES 
(1, 'zhangsan', '123456', 'zhangsan@foooor.com', 12, NOW(), NOW()),
(2, 'lisi', '1234qwer', 'lisi@foooor.com', 13, NOW(), NOW()),
(3, 'wangwu', '88888888', 'wangwu@foooor.com', 14, NOW(), NOW());
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

创建了一个 foooor_db2foooor_db 是一样的,就是数据不一样。

# 2 引入依赖

需要引入一个 Spring Boot 多数据源启动器。

<dependency>
    <groupId>com.baomidou</groupId>
    <!-- springboot3的版本 -->
    <artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
    <version>4.3.1</version>
</dependency>
1
2
3
4
5
6

添加完成,右键 -> Maven -> Reload Project

# 3 配置多数据源

在 SpringBoot 的配置文件中配置数据源:

application.yaml

# 多数据源配置
spring:
  datasource:
    dynamic:
      enabled: true #启用动态数据源,默认true
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      grace-destroy: false #是否优雅关闭数据源,默认为false,设置为true时,关闭数据源时如果数据源中还存在活跃连接,至多等待10s后强制关闭
      datasource:
        master:
          url: jdbc:mysql://localhost:3306/foooor_db?useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
        slave_1:
          url: jdbc:mysql://localhost:3306/foooor_db2?useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver


# mybaits-plus配置,和多数据源没关系
mybatis-plus:
  # MyBatis Mapper所对应的XML文件位置,这里暂时没用到
  mapper-locations: classpath*:/mapper/*Mapper.xml
  global-config:
    # 关闭MybatisPlus控制台打印的banner
    banner: false
    db-config:
      table-prefix: tb_
      table-underline: true
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

上面配置了两个数据源,起名字叫 masterslave_1 ,并指定了数据库的连接信息。

# 4 编写测试方法

在 UserServiceImpl 中编写两个方法,获取所有的用户,但是指定使用的数据源不同。

UserServiceImpl.java

package com.foooor.helloplus.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.foooor.helloplus.service.IUserService;
import com.foooor.helloplus.mapper.UserMapper;
import com.foooor.helloplus.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    /**
     * 从master获取所有用户
     */
    public List<User> getAllUserFromDb1() {
        return userMapper.selectList(null);
    }


    /**
     * 从slave_1获取所有用户
     */
    @DS("slave_1")
    public List<User> getAllUserFromDb2() {
        return userMapper.selectList(null);
    }

}
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
34
35
  • getAllUserFromDb2() 方法上,通过 @DS("slave_1") 注解指定时候用 slave_1 数据源。

  • getAllUserFromDb1() 没有指定数据源,默认使用 master 数据源,也可以通过 @DS("master") 来指定。

  • @DS 注解也可以添加到类上,表示整个类使用哪个数据源,也可以类上和方法上同时添加,那么采用就近原则,优先使用方法上指定的数据源。


在 Service 接口中也添加对应的方法:

package com.foooor.helloplus.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.foooor.helloplus.pojo.User;
import java.util.List;

public interface IUserService extends IService<User> {

    /**
     * 从master获取所有用户
     */
    List<User> getAllUserFromDb1();


    /**
     * 从slave_1获取所有用户
     */
    List<User> getAllUserFromDb2();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 5 测试

编写一个测试类,注入 UserService,然后同时调用 Service 中的两个方法获取数据:

package com.foooor.helloplus;

import com.foooor.helloplus.pojo.User;
import com.foooor.helloplus.service.IUserService;
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;

import java.util.*;

@Slf4j
@SpringBootTest
public class QueryTests {

    @Autowired
    private IUserService userService;

    /**
     * 测试QueryWrapper
     */
    @Test
    void testQueryWrapper() {
        List<User> userList1 = userService.getAllUserFromDb1();
        log.info("userList1: {}", userList1);

        List<User> userList2 = userService.getAllUserFromDb2();
        log.info("userList2: {}", userList2);
    }
}
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

这样就可以从两个数据库中获取数据了。

注意,如果是一个实体类对应两个数据库的表,那么实体类的属性要与两个数据库中的字段对应。