【Java】再谈谈动态数据源的事情

连着两天都遇到了这个从数据库读取表数据构造数据源,而不是在配置文件中写死数据源的业务场景!第一次发文章,没想到又给到了动态数据源!猿粪啊
先说一下具体的场景:大体上是有个基础库,库中有个表比较特殊,保存的是数据源信息,系统希望能通过这个表来维护数据源,实现数据源的管理,当然只是表数据crud的话,也没必要写这个了不是!主要是他还希望这个表构造的数据源,也能执行正常执行相关的crud操作!
首先介绍一个类:AbstractRoutingDataSource,看路由就大概知道他能干啥了,它的原理其实也很简单,他维护了一个Map<Object,DataSource>和默认数据源,有一个抽象方法就是生成map的key,如果从map中找不到数据源,那就使用默认数据源;
说一下具体的实现方式
1:springboot默认配置数据源的配置,咱们合理的利用起来,做成默认数据源;【Java】再谈谈动态数据源的事情
2:实现自己的AbstractRoutingDataSource,
【Java】再谈谈动态数据源的事情
【Java】再谈谈动态数据源的事情
【Java】再谈谈动态数据源的事情

解释一下:
1:EnvironmentAware,因为此时数据源还在实例化的过程,触发时机很早,所以为了获得yml中的默认数据源的配置,我们实现了EnvironmentAware接口,此接口的回调在ApplicationContextAwareProcessor(实现了BeanPostProcessor).postProcessBeforeInitialization中触发的,所以他的时机会早于AbstractRoutingDataSource.afterPropertiesSet的方法,afterPropertiesSet中又进行了相关操作,所以EnvironmentAware的回调方法,相对来说比较合适做从默认数据源中读取表结构的操作
2:因为这个数据源就是我们注入到容器中的数据源,容器中也只会有这一个数据源,所以在此时我们要读取数据源的话,orm框架或者jdbcTemplate都没有实例化,要么我们自己去new jdbcTemplate,我这里选择的是直接使用jdbc代码
3:抽象方法determineCurrentLookupKey,它获取的ThreadLocal中的数据,ThreadLocal中的数据,是通过aop的方式丢进去的,可以根据业务可以自行决定设置key的来源【Java】再谈谈动态数据源的事情

然后 就完了! - -
后面就是激动人心的效果了,测试一下效果!
1:清除数据源表数据
2:数据源表插入数据并且直接根据key指定数据源查询数据
执行前:
【Java】再谈谈动态数据源的事情

【Java】再谈谈动态数据源的事情

【Java】再谈谈动态数据源的事情
【Java】再谈谈动态数据源的事情
【Java】再谈谈动态数据源的事情

可以看到 尽管我们key指定了test,但是因为数据源表没有数据,所以还是访问的默认数据源framework中的数据

3:插入数据源
【Java】再谈谈动态数据源的事情

【Java】再谈谈动态数据源的事情

这个时候数据源表已经插入了数据,查询接口也是返回的test库中的数据了!完美解决

多说一句话:AbstractRoutingDataSource想要做事务下面的切换数据源,是不行的;因为我是用mybatis,在同一个事务下复用connection和sqlsession,你切换了数据源其实并没有什么用;如果事务下也需要切换数据源,可以优先考虑jdbcTemplate,并且自行控制事务;实际上更推荐微服务,他更香

最后就是代码了 我直接丢网盘
链接: https://pan.baidu.com/s/1I51F... 提取码: 97sg 复制这段内容后打开百度网盘手机App,操作更方便哦

以上是 【Java】再谈谈动态数据源的事情 的全部内容, 来源链接: utcz.com/a/105034.html

回到顶部