Skip to content

Mybatis Plus 多数据源

TIP

MyBatis-Plus 提供了动态数据源切换功能,可以轻松实现读写分离和多库操作。

引入依赖

xml
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.6.1</version>
</dependency>

配置多数据源

yaml
spring:
  datasource:
    dynamic:
      primary: master                      # 默认数据源
      strict: false                        # 未找到数据源是否抛出异常
      datasource:
        master:
          url: jdbc:mysql://localhost:3306/demo?useSSL=false
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver

        slave_1:
          url: jdbc:mysql://192.168.1.2:3306/demo?useSSL=false
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver

        slave_2:
          url: jdbc:mysql://192.168.1.3:3306/demo?useSSL=false
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver

使用 @DS 注解

java
// 默认使用主库(master)
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    // 查询操作使用从库
    @DS("slave_1")
    public User getUser(Long id) {
        return userMapper.selectById(id);
    }

    // 列表查询轮询从库
    @DS("slave_2")
    public List<User> getAllUsers() {
        return userMapper.selectList(null);
    }

    // 写操作使用主库(默认)
    public void saveUser(User user) {
        userMapper.insert(user);
    }
}

读写分离

java
// 在 Service 上标记 @DSTransactional 确保事务内使用同一数据源
@Service
@DSTransactional
public class OrderService {

    @DS("slave")
    public Order getOrder(Long id) {
        return orderMapper.selectById(id);
    }

    @DS("master")
    public void createOrder(Order order) {
        orderMapper.insert(order);
    }
}

动态切换

java
// 手动切换
public void businessMethod() {
    try {
        DynamicDataSourceContextHolder.push("slave_1");
        // 查询操作
        List<User> users = userMapper.selectList(null);
    } finally {
        DynamicDataSourceContextHolder.poll();
    }
}

TIP

多数据源场景下,事务默认只对主库生效。@DSTransactional 可以在多个数据源间保持事务一致性。