dynamic多数据源整合springboot以及遇到的问题

1:引入依赖

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

2:编写配置文件

复制代码
  datasource:
    dynamic:
      #默认数据源
      primary:db1
      #严格模式
      strict: true
      datasource:
        db1:
          url: jdbc:mysql......
          username: root
          password: root
          driver-class-name: com.mysql.cj.jdbc.Driver
        db2:
          url: jdbc:mysql......
          username: root
          password: root
          driver-class-name: com.mysql.cj.jdbc.Driver
  #连接池 type: com.alibaba.druid.pool.DruidDataSource
复制代码

3:使用:

在需要使用db2的controller上 直接增加这个注解,下面就会在使用过程中,改变链接 指向db2的链接

当然,再次过程中,尽量不要同时使用其他datasource注入相关的配置文件,比如自己实现的aop多数据源配置等

@DS("db2")public class TestController extends BaseController {}

注意事项:

由于是使用线程变量来做的数据源指向,所以在多线程情况下,它会出现找不到数据源,然后就会使用默认数据源的情况。

解决方案之一:

比较简单的处理方案是,给当前线程设置一个指定的数据源

复制代码
/**
     * 切换数据源的显示指定
     *
     * @param run 运行的函数
     * @param ds  数据源名称
     */
    public static void run(TaskRun run, String ds) {
        try {
            if (StringUtils.isNotEmpty(ds)) {
                DynamicDataSourceContextHolder.push(ds);
                log.warn(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>切换当前数据源为:{}", ds);
                run.exec();
            } else {
                log.error("数据源不能为空!不使用默认数据源执行!");
            }
        } finally {
            DynamicDataSourceContextHolder.clear();
            log.warn(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>清除当前数据源:{}", ds);
        }
    }

    public static void main(String[] args) {
        new Thread(()->{
            run(()->{
                System.out.println("使用db1的数据源");
            },"db1");
        }).start();

        new Thread(()->{
            run(()->{
                System.out.println("使用db2的数据源");
            },"db2");
        }).start();

        new Thread(()->{
            run(()->{
                System.out.println("使用db3的数据源");
            },"db3");
        }).start();
    }
复制代码

上面方法的接口函数

public interface TaskRun {

    /**
     * 执行方法
     */
    void exec();
}

 

当然上面的main方法里面三个函数都只是打印了一下并没有真正链接那些库,实际测试时,只要链接不同的库,就能实现不同的功能,上面方法执行后的日志如下

复制代码
11:05:19.580 [Thread-0] WARN com.demo.utils.DataSourceUtils - >>>>>>>>>>>>>>>>>>>>>>>>>>>>>切换当前数据源为:db1
        11:05:19.580 [Thread-1] WARN com.demo.utils.DataSourceUtils - >>>>>>>>>>>>>>>>>>>>>>>>>>>>>切换当前数据源为:db2
        使用db2的数据源
        11:05:19.580 [Thread-2] WARN com.demo.utils.DataSourceUtils - >>>>>>>>>>>>>>>>>>>>>>>>>>>>>切换当前数据源为:db3
        使用db3的数据源
        使用db1的数据源
        11:05:19.584 [Thread-1] WARN com.demo.utils.DataSourceUtils - >>>>>>>>>>>>>>>>>>>>>>>>>>>>>清除当前数据源:db2
        11:05:19.584 [Thread-2] WARN com.demo.utils.DataSourceUtils - >>>>>>>>>>>>>>>>>>>>>>>>>>>>>清除当前数据源:db3
        11:05:19.585 [Thread-0] WARN com.demo.utils.DataSourceUtils - >>>>>>>>>>>>>>>>>>>>>>>>>>>>>清除当前数据源:db1
复制代码

可以看出,数据源的变量已经改变

posted @   鸭猪是的念来过倒  阅读(679)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示