RuoYi-Vue-Plus (多数据源配置)

一、依赖以及配置

1.1依赖

ruoyi-common 下面引入依赖


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

父pom.xml 下面,控制版本

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

 对应版本:

<dynamic-ds.version>3.5.2</dynamic-ds.version>
 1.2  yml中配置
  •  datasource: 配置项下面配置了master、slave2个数据源
  • master、slave 这2个数据源 共用hikari连接池配置
  • 此处演示了oracle 等其他数据源配置
--- # 数据源配置
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
    dynamic:
      # 性能分析插件(有性能损耗 不建议生产环境使用)
      p6spy: true
      # 设置默认的数据源或者数据源组,默认值即为 master
      primary: master
      # 严格模式 匹配不到数据源则报错
      strict: true
      datasource:
        # 主库数据源
        master:
          type: ${spring.datasource.type}
          driverClassName: com.mysql.cj.jdbc.Driver
          # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
          # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
          url: jdbc:mysql://localhost:3306/ry-vue-plus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
          username: root
          password: root
        # 从库数据源  lazy: true 用不到不会加载从库
        slave:
          lazy: true
          type: ${spring.datasource.type}
          driverClassName: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/ry-vue-plus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
          username: root
          password: root
#        oracle:
#          type: ${spring.datasource.type}
#          driverClassName: oracle.jdbc.OracleDriver
#          url: jdbc:oracle:thin:@//localhost:1521/XE
#          username: ROOT
#          password: root
#        postgres:
#          type: ${spring.datasource.type}
#          driverClassName: org.postgresql.Driver
#          url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
#          username: root
#          password: root
#        sqlserver:
#          type: ${spring.datasource.type}
#          driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
#          url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
#          username: SA
#          password: root
      hikari:
        # 最大连接池数量
        maxPoolSize: 20
        # 最小空闲线程数量
        minIdle: 10
        # 配置获取连接等待超时的时间
        connectionTimeout: 30000
        # 校验超时时间
        validationTimeout: 5000
        # 空闲连接存活最大时间,默认10分钟
        idleTimeout: 600000
        # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
        maxLifetime: 1800000
        # 多久检查一次连接的活性
        keepaliveTime: 30000

解释:

 type: ${spring.datasource.type} ,引用的是配置:
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource

 二、连接测试

2.1未加上多数据源注解

默认连接主库:

@RestController
@Slf4j
@SaIgnore
@RequiredArgsConstructor
public class DynamicController {
    private final ITestDemoService iTestDemoService;

    @GetMapping("testDynamic1")
    public void test() {
        TestDemoVo testDemoVo = iTestDemoService.queryById(2L);
        Console.log("打印数据:{}", testDemoVo);

    }
}

打印结果:
 

打印数据:TestDemoVo(id=2, deptId=102, userId=3, orderNum=2, testKey=主库节点, value=22222, createTime=Tue Jul 23 10:18:35 GMT+08:00 2024, createBy=null, updateTime=null, updateBy=null)
2024-07-23 10:39:55 [XNIO-1 task-1] INFO  c.r.f.i.PlusWebInvokeTimeInterceptor
 - [PLUS]结束请求 => URL[GET /testDynamic1],耗时:[49]毫秒

2.2 加上多数据源注解 

 @DS("slave")后,打印从库节点数据,如下:

  @GetMapping("testDynamic1")
    @DS("slave")
    public void test() {
        TestDemoVo testDemoVo = iTestDemoService.queryById(2L);
        Console.log("打印数据:{}", testDemoVo);

    }

打印结果:

打印数据:TestDemoVo(id=2, deptId=102, userId=3, orderNum=2, testKey=从库节点, value=22222, createTime=Tue Jul 23 10:18:35 GMT+08:00 2024, createBy=null, updateTime=null, updateBy=null)
2024-07-23 11:14:09 [XNIO-1 task-1] INFO  c.r.f.i.PlusWebInvokeTimeInterceptor
 - [PLUS]结束请求 => URL[GET /testDynamic1],耗时:[235]毫秒

 注意,失效场景:

  • 持久层使用 @DS注解,只会在自定义的方法上生效
  • 如果标注在 BaseMapper  接口是不会生效,还是查询主库,原因是selectById 是内部调用this.,如下代码。而@DS注解的AOP是对内部调用无法产生作用。所以注解要写在AOP可以作用的地方
  •    /**
         * 根据 ID 查询
         */
        default <C> C selectVoById(Serializable id, Class<C> voClass) {
            T obj = this.selectById(id);
            if (ObjectUtil.isNull(obj)) {
                return null;
            }
            return BeanCopyUtils.copy(obj, voClass);
        }

  • 重点:@DS注解注解,推荐写在实现类的方法上

 错误演示:selectById是MyBatis是自带事项方法,不生效如下;

  /**
     *不会生效:selectById 是 BaseMapper 定义接口
     */
    @Override
    @DS("slave")
    TestDemo selectById(Serializable id);

    /**
     *会生效:selectByIdOfMy 是自定义接口
     */
    @DS("slave")
    TestDemo selectByIdOfMy(Serializable id);

 

三、轮询访问

3.1演示
  • 如图下面配置3个数据源 :slave_1、slave_2、slave_3
  • 如果注解还是这样写:    @DS("slave")  ,则会循环调用3个数据源(默认机制)
   @GetMapping("testDynamic1")
    @DS("slave")
    public void test() {
        TestDemoVo testDemoVo = iTestDemoService.queryById(2L);
        Console.log("打印数据:{}", testDemoVo);

    }

打印结果:

打印数据:TestDemoVo(id=2, deptId=102, userId=3, orderNum=2, testKey=从库节点1, value=111, createTime=Tue Jul 23 10:18:35 GMT+08:00 2024, createBy=null, updateTime=null, updateBy=null)
2024-07-23 11:20:09 [XNIO-1 task-1] INFO  c.r.f.i.PlusWebInvokeTimeInterceptor
 - [PLUS]结束请求 => URL[GET /testDynamic1],耗时:[235]毫秒


打印数据:TestDemoVo(id=2, deptId=102, userId=3, orderNum=2, testKey=从库节点2, value=222, createTime=Tue Jul 23 10:18:35 GMT+08:00 2024, createBy=null, updateTime=null, updateBy=null)
2024-07-23 11:21:11 [XNIO-1 task-1] INFO  c.r.f.i.PlusWebInvokeTimeInterceptor
 - [PLUS]结束请求 => URL[GET /testDynamic1],耗时:[212]毫秒



打印数据:TestDemoVo(id=2, deptId=102, userId=3, orderNum=2, testKey=从库节点3, value=333, createTime=Tue Jul 23 10:18:35 GMT+08:00 2024, createBy=null, updateTime=null, updateBy=null)
2024-07-23 11:22:13 [XNIO-1 task-1] INFO  c.r.f.i.PlusWebInvokeTimeInterceptor
 - [PLUS]结束请求 => URL[GET /testDynamic1],耗时:[187]毫秒

 slave_1、slave_2、slave_3 数据源配置:

--- # 多数据源配置 HikariDataSource
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
    dynamic:
      # 性能分析插件(有性能损耗 不建议生产环境使用)
      p6spy: true
      # 设置默认的数据源或者数据源组,默认值即为 master
      primary: master
      # 严格模式 匹配不到数据源则报错
      strict: true
      datasource:
        # 主库数据源1
       slave_1:
          type: ${spring.datasource.type}
          driverClassName: com.mysql.cj.jdbc.Driver
          # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
          # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
          url: jdbc:mysql://localshost:3306/ry-vue-plus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
          username: root
          password: root
        # 从库数据源2
        slave_2:
          lazy: true
          type: ${spring.datasource.type}
          driverClassName: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localshost:3306/ry-vue-plus2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
          username: root
          password: root
         # 从库数据源3
        slave_3:
          lazy: true
          type: ${spring.datasource.type}
          driverClassName: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localshost:3306/ry-vue-plus2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
          username: root
          password: root
3.2数据源策略
  1. DynamicDataSourceProperties.class 定义了每一个数据源,以及对应动态数据源策略
  2. LoadBalanceDynamicDataSourceStrategy就是默认负载均衡策略
    /**
     * 每一个数据源
     */
    private Map<String, DataSourceProperty> datasource = new LinkedHashMap<>();
    /**
     * 多数据源选择算法clazz,默认负载均衡算法
     */
    private Class<? extends DynamicDataSourceStrategy> strategy = LoadBalanceDynamicDataSourceStrategy.class;

 查看器策略接口:com.baomidou.dynamic.datasource.strategy.DynamicDataSourceStrategy  的实现类有2个:

  • RandomDynamicDataSourceStrategy.class  随机策略
  • LoadBalanceDynamicDataSourceStrategy 负载均衡策略(默认

3.3 配置策略

指定 strategy 属性就行如下,指定RandomDynamicDataSourceStrategy随机策略:

。。。。。。。省里配置     
 hikari:
        # 最大连接池数量
        maxPoolSize: 20
        # 最小空闲线程数量
        minIdle: 10
        # 配置获取连接等待超时的时间
        connectionTimeout: 30000
        # 校验超时时间
        validationTimeout: 5000
        # 空闲连接存活最大时间,默认10分钟
        idleTimeout: 600000
        # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
        maxLifetime: 1800000
        # 多久检查一次连接的活性
        keepaliveTime: 30000
  strategy: com.baomidou.dynamic.datasource.strategy.RandomDynamicDataSourceStrategy
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

syfjava

请博主喝杯蜜雪冰城

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值