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

连着两天都遇到了这个从数据库读取表数据构造数据源,而不是在配置文件中写死数据源的业务场景!第一次发文章,没想到又给到了动态数据源!猿粪啊

先说一下具体的场景:大体上是有个基础库,库中有个表比较特殊,保存的是数据源信息,系统希望能通过这个表来维护数据源,实现数据源的管理,当然只是表数据crud的话,也没必要写这个了不是!主要是他还希望这个表构造的数据源,也能执行正常执行相关的crud操作!

首先介绍一个类:AbstractRoutingDataSource,看路由就大概知道他能干啥了,它的原理其实也很简单,他维护了一个Map和默认数据源,有一个抽象方法就是生成map的key,如果从map中找不到数据源,那就使用默认数据源;

说一下具体的实现方式

1:springboot默认配置数据源的配置,咱们合理的利用起来,做成默认数据源;85c09853200ade7e5fb4a1c7e0d51d99.png

2:实现自己的AbstractRoutingDataSource,

ca1efbf6c73966bba8d73fad33bd6cde.png

e5deeb275735e60c0c9911ee02a13369.png

679e9380e101a4005b5f66643f90c476.png

解释一下:

1:EnvironmentAware,因为此时数据源还在实例化的过程,触发时机很早,所以为了获得yml中的默认数据源的配置,我们实现了EnvironmentAware接口,此接口的回调在ApplicationContextAwareProcessor(实现了BeanPostProcessor).postProcessBeforeInitialization中触发的,所以他的时机会早于AbstractRoutingDataSource.afterPropertiesSet的方法,afterPropertiesSet中又进行了相关操作,所以EnvironmentAware的回调方法,相对来说比较合适做从默认数据源中读取表结构的操作

2:因为这个数据源就是我们注入到容器中的数据源,容器中也只会有这一个数据源,所以在此时我们要读取数据源的话,orm框架或者jdbcTemplate都没有实例化,要么我们自己去new jdbcTemplate,我这里选择的是直接使用jdbc代码

3:抽象方法determineCurrentLookupKey,它获取的ThreadLocal中的数据,ThreadLocal中的数据,是通过aop的方式丢进去的,可以根据业务可以自行决定设置key的来源e56be594115778a7d7b17aa39c81ec32.png

然后 就完了! – –

后面就是激动人心的效果了,测试一下效果!

1:清除数据源表数据

2:数据源表插入数据并且直接根据key指定数据源查询数据

执行前:

dabc43496b860b303e7f95ae61ff6d42.png

360cff06e5e4ae34f58d48bb841819ce.png

dbbf6273e22cea2a7ce60bc3f56597c1.png

a0937aa77c975e3b573338b37ded1f62.png

d5ab0c9f950a0f10967612c07c25d78e.png

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

3:插入数据源

8781f5a1a5c58da88a1f107c98dee179.png

5b7b4aba9c1d156c749b31da5181adc9.png

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

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

最后就是代码了 我直接丢网盘

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值