前言

随着项目规模的扩大,单一数据源已无法满足复杂业务需求,多数据源(动态数据源)应运而生。本文将介绍两种 MyBatis-Plus 的多数据源扩展插件:开源生态的 dynamic-datasource 和 企业级生态的 mybatis-mate


一、dynamic-datasource

dynamic-datasource 是一个开源的 Spring Boot 多数据源启动器,提供了丰富的功能,包括数据源分组、敏感信息加密、独立初始化表结构等。

1. 特性

  • 数据源分组:适用于多种场景,如读写分离、一主多从等。
  • 敏感信息加密:使用 ENC() 加密数据库配置信息。
  • 独立初始化:支持每个数据库独立初始化表结构和数据库。
  • 自定义注解:支持自定义注解,需继承 DS
  • 简化集成:提供对 DruidHikariCP 等连接池的快速集成。
  • 组件集成:支持 Mybatis-PlusQuartz 等组件的集成方案。
  • 动态数据源:支持项目启动后动态增加或移除数据源。
  • 分布式事务:提供基于 Seata 的分布式事务方案。

2. 约定

  • 本框架专注于数据源切换,不限制具体操作。
  • 配置文件中以下划线_ 分割的数据源首部为组名。
  • 切换数据源可以是组名或具体数据源名。
  • 默认数据源名为 master,可通过 spring.datasource.dynamic.primary 修改。
  • 方法上的注解优先于类上的注解。

3. 使用方法

3.1 引入依赖

<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
  <version>${version}</version>
</dependency>

3.2 配置数据源

spring:
  datasource:
    dynamic:
      primary: master
      strict: false
      datasource:
        master:
          url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
        slave_1:
          url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
        slave_2:
          url: ENC(xxxxx)
          username: ENC(xxxxx)
          password: ENC(xxxxx)
          driver-class-name: com.mysql.jdbc.Driver

3.3 使用 @DS 切换数据源

@Service
@DS("slave")
public class UserServiceImpl implements UserService {

  @Autowired
  private JdbcTemplate jdbcTemplate;

  @Override
  @DS("slave_1")
  public List selectByCondition() {
    return jdbcTemplate.queryForList("select * from user where age >10");
  }
}

更多使用教程请参考Dynamic-Datasource 官网

二、mybatis-mate

mybatis-mate 是一个 MyBatis-Plus 的付费企业组件,内置很多好用的高级特性,其中包括多数据源扩展组件,提供了高效简单的多数据源支持。

1.特性

  • 注解 @Sharding:支持通过注解切换数据源。
  • 配置:支持灵活的数据源配置。
  • 动态加载卸载:支持动态加载和卸载数据源。
  • 多数据源事务:支持 JTA Atomikos 分布式事务。

2.使用方法

2.1 配置数据源

mybatis-mate:
  sharding:
    primary: mysql
    datasource:
      mysql:
        - key: node1
          ...
        - key: node2
          cluster: slave
          ...
      postgres:
        - key: node1
          ...

2.2 使用 @Sharding 切换数据源

@Mapper
@Sharding("mysql")
public interface UserMapper extends BaseMapper<User> {

    @Sharding("postgres")
    Long selectByUsername(String username);

}

2.3 切换指定数据库节点

// 切换到 mysql 从库 node2 节点
ShardingKey.change("mysqlnode2");

更多使用示例请参考

多数据源动态加载卸载:👉 mybatis-mate-sharding-dynamic

多数据源事务(jta atomikos):👉 mybatis-mate-sharding-jta-atomikos

三、实战

这里我们使用dynamic-datasource 来展示多数据源的使用

1. 引入库

<!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-spring-boot3-starter -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
    <version>4.3.1</version>
</dependency>
<!-- 我本地starter没有把下面包关联进来,我手动引入了一遍 -->
<!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-spring -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring</artifactId>
    <version>4.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-creator -->
 <dependency>
     <groupId>com.baomidou</groupId>
     <artifactId>dynamic-datasource-creator</artifactId>
     <version>4.3.1</version>
 </dependency>

在这里插入图片描述
看配置像是缺少了${project.version}这个变量,我已经向官方提交issue,期待回复吧~

2. 配置

spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: true #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          url: jdbc:mysql://xx.xx.xx.xx:3306/master
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
        slave_1:
          url: jdbc:mysql://xx.xx.xx.xx:3306/slave
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
       #以上会配置一个默认库master,一个组slave下有一个子库slave

3. 使用 @DS 切换数据源

package org.example.springboot3.mybatisplus.service;

import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.util.List;

/**
 * Create by zjg on 2024/7/4
 */

@Service
@DS("master")
public class UserServiceImpl{

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public List selectFromMaster() {
        return jdbcTemplate.queryForList("select * from user");
    }

    @DS("slave")
    public List selectFromSlave() {
        return jdbcTemplate.queryForList("select * from user");
    }
}

4. 测试类

@SpringBootTest
public class SampleTest {

    @Autowired
    private UserServiceImpl userService;

    @Test
    public void dynamicDatasource() {
        List master = userService.selectFromMaster();
        List slave = userService.selectFromSlave();
        System.out.println(master);
        System.out.println(slave);
    }
}

5. 测试结果

[{id=1, name=master, age=18, email=master@qq.com, gender=0, status=active, create_time=2024-07-04 21:40:43.0, update_time=2024-07-04 21:40:46.0, deleted=0}]
[{id=1, name=slave, age=18, email=slave@qq.com, gender=0, status=active, create_time=2024-07-04 21:40:43.0, update_time=2024-07-04 21:40:46.0, deleted=0}]

sql语句已上传附件,欢迎下载使用


总结

回到顶部

通过上述介绍,我们可以看到 dynamic-datasourcemybatis-mate 都提供了强大的多数据源支持,开发者可以根据项目需求选择合适的插件来实现数据源的灵活管理。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐