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
可以看出,数据源的变量已经改变