【转】spring boot-mybatis plus 多数据源

1.基本介绍

(1)dynamic-datasource-spring-boot-starter 是一个基于 springboot 的快速集成多数据源的启动器。其支持 Jdk 1.7+,SpringBoot 1.4.x 1.5.x 2.0.x。

注意:该插件可以不依赖 MyBatis-Plus,可以独立使用。

(2)它主要用于读写分离,一主多从的环境。(当然也可以纯粹当成多库使用)
一主多从的环境下数据库分工:

  • 主数据库建议只执行 INSERT、UPDATE、DELETE 操作。
  • 从数据库建议只执行 SELECT 操作。

2.功能特性

  • 数据源分组,适用于多种场景:纯粹多库、读写分离、一主多从、混合模式。
  • 内置敏感参数加密和启动初始化表结构 schema 数据库 database。
  • 提供对 Druid,Mybatis-Plus,P6sy,Jndi 的快速集成。
  • 简化 Druid 和 HikariCp 配置,提供全局参数配置。
  • 提供自定义数据源来源接口(默认使用 yml 或 properties 配置)。
  • 提供项目启动后增减数据源方案。
  • 提供 Mybatis 环境下的 纯读写分离 方案。
  • 使用 spel 动态参数解析数据源,如从 session,header 或参数中获取数据源。(多租户架构神器)
  • 提供多层数据源嵌套切换。(ServiceA >>> ServiceB >>> ServiceC,每个 Service 都是不同的数据源)
  • 提供“不使用注解”而使用“正则”或 spel 来切换数据源方案(实验性功能)。
  • 基于 seata 的分布式事务支持。

3.安装配置

(1)首先编辑项目的 pom.xml 文件,引入 dynamic-datasource-spring-boot-starter 依赖:

<!-- 多数据源 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.1.1</version>
</dependency>

(2)接着配置数据源,比如下面我们配置了一个主库、两个从库。

提示:

  • 配置文件中所有以下划线 _ 分割的数据源“首部”即为组的名称,相同组名称的数据源会放在一个组下。
  • 默认的数据源名称为 master ,我们可以通过 spring.datasource.dynamic.primary 修改。
spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候回抛出异常,不启动会使用默认数据源.
      datasource:
        master:
          url: jdbc:mysql://xx.xx.xx.xx:3306/hangge?serverTimezone=Asia/Shanghai
          username: root
          password: hangge1234
          type: com.alibaba.druid.pool.DruidDataSource
        slave_1:
          url: jdbc:mysql://xx.xx.xx.xx:3307/hangge?serverTimezone=Asia/Shanghai
          username: root
          password: hangge1234
          type: com.alibaba.druid.pool.DruidDataSource
        slave_2:
          url: jdbc:mysql://xx.xx.xx.xx:3308/hangge?serverTimezone=Asia/Shanghai
          username: root
          password: hangge1234
          type: com.alibaba.druid.pool.DruidDataSource
  • 或者我们也可以配置多主多从:
spring:
  datasource:
    dynamic:
      datasource:
        master_1:
        master_2:
        slave_1:
        slave_2:
        slave_3:
  • 或者纯粹多库(记得设置 primary):
spring:
  datasource:
    dynamic:
      datasource:
        mysql:
        oracle:
        sqlserver:
        postgresql:
        h2:
  • 或者混合配置:
spring:
  datasource:
    dynamic:
      datasource:
        master:
        slave_1:
        slave_2:
        oracle_1:
        oracle_2:

(3)最后代码中使用 @DS 切换数据源。

  • @DS 可以注解在方法上和类上。如果同时存在,方法注解优先于类上注解。强烈建议注解在 service 实现或 mapper 接口方法上。
  • @DS(“xxx”) 指定使用 xxx 这个数据源,xxx 可以为组名也可以为具体某个库的名称。如果是组名则切换时采用负载均衡算法切换。如果指定的组名或者库不存在,则自动使用默认数据源(主库)
  • 如果没有 @DS,则使用默认数据源(主库)
  • 如果设置了 @DS 但没有指定某个组或者库,则根据 DynamicDataSourceStrategy 策略,选择一个从库。默认负载均衡策略。
@Service
@DS("slave")
public class UserServiceImpl implements UserService {
 
  @Autowired
  private JdbcTemplate jdbcTemplate;
 
  public List<Map<String, Object>> selectAll() {
    return  jdbcTemplate.queryForList("select * from user");
  }
   
  @Override
  @DS("slave_1")
  public List<Map<String, Object>> selectByCondition() {
    return  jdbcTemplate.queryForList("select * from user where age >10");
  }
}
  • 在 mybatis 环境下也可注解在 mapper 接口层。比如下面我们在主数据库上执行 INSERT、UPDATE、DELETE 操作,而从数据库执行 SELECT 操作。
@DS("master")
public interface UserMapper {
 
  @Insert("INSERT INTO user (name,age) values (#{name},#{age})")
  boolean addUser(@Param("name") String name, @Param("age") Integer age);
 
  @Update("UPDATE user set name=#{name}, age=#{age} where id =#{id}")
  boolean updateUser(@Param("id") Integer id, @Param("name") String name, @Param("age") Integer age);
 
  @Delete("DELETE from user where id =#{id}")
  boolean deleteUser(@Param("id") Integer id);
 
  @Select("SELECT * FROM user")
  @DS
  List<User> selectAll();
}

附:样例演示

1.基本用法

(1)假设我们有 hangge 与 hangge2 两个数据库,两个库中都有 user_info 这张表(不过两个库里数据不一样):
【转】spring boot-mybatis plus 多数据源_第1张图片【转】spring boot-mybatis plus 多数据源_第2张图片
(2)在配置文件中一个设置为主库,一个设置为从库:

spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候回抛出异常,不启动会使用默认数据源.
      datasource:
        master:
          url: jdbc:mysql://localhost:3306/hangge?serverTimezone=Asia/Shanghai
          username: root
          password: hangge1234
          type: com.alibaba.druid.pool.DruidDataSource
        slave:
          url: jdbc:mysql://localhost:3306/hangge2?serverTimezone=Asia/Shanghai
          username: root
          password: hangge1234
          type: com.alibaba.druid.pool.DruidDataSource

(3)默认情况下,如果不做额外配置的话,都是操作主库:

@RestController
public class HelloController {
 
    @Autowired
    UserInfoService userInfoService;
 
    @GetMapping("/test")
    public List<UserInfo> test() {
        return userInfoService.list();
    }
}

(4)使用 @DS 切换数据源,这里我们将 UserInfoService 数据源切换成从库。再次进行查询,可以发现数据源确实发生变化。

@DS("slave")
public interface UserInfoService extends IService<UserInfo> {
 
}

2.负载均衡

(1)如果数据源指定的是一个分组,且该分组下有多个数据库,那么会自动进行负载均衡。比如我们在上面样例上稍作修改,配置了两个从库:

spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候回抛出异常,不启动会使用默认数据源.
      datasource:
        master:
          url: jdbc:mysql://localhost:3306/hangge?serverTimezone=Asia/Shanghai
          username: root
          password: hangge1234
          type: com.alibaba.druid.pool.DruidDataSource
        slave_1:
          url: jdbc:mysql://localhost:3306/hangge2?serverTimezone=Asia/Shanghai
          username: root
          password: hangge1234
          type: com.alibaba.druid.pool.DruidDataSource
        slave_2:
          url: jdbc:mysql://localhost:3306/hangge?serverTimezone=Asia/Shanghai
          username: root
          password: hangge1234
          type: com.alibaba.druid.pool.DruidDataSource

(2)UserInfoService 同样通过 @DS 注解指定使用 slave 这个分组:

@DS("slave")
public interface UserInfoService extends IService<UserInfo> {
 
}

(3)多次刷新浏览器,可以发现数据轮流从两个库中获取,说明负载均衡生效了。

【转】spring boot-mybatis plus 多数据源_第3张图片
【转】spring boot-mybatis plus 多数据源_第4张图片

你可能感兴趣的:(Spring相关,springboot,mybatis,plus)