背景
希望实现多数据源切换,如某些sql的执行可以指定使用另外一个数据源
方案
方案1:
借助于JPA对双数据源的支持,根据package来区分使用哪个数据源
代码参考:https://gitee.com/constfafa/spring_springboot_learning/tree/master/springboot-multi-datasource
优点:简单
缺点:只能做到package粒度
方案2:
在sql语句级别进行控制,直接采用api编程的方式,基于不同的jdbcTemplate
优点:可以做到sql语句粒度
缺点:使用jdbcTemplate太过底层,与现代的声明式编程方式不符
方案3:
基于ThreadLocal,及org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
实现原理:
切面表达的是其运用在使用了@HfiDataSource的方法上,利用ThreadLocal,将String prodDb还是queryDb放入执行线程的threadLocalMap中。
当执行的时候,利用org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#determineCurrentLookupKey方法,设定好底层使用的数据源dataSource bean
优点:可以做到线程粒度,并采用了声明式编程方式
相当于对方案1和方案2进行了折中处理,此方案侵入式很小,代码改造成本很低
缺点:要考虑涉及到多个数据库的事务操作问题。并且由于其是基于线程的,多个线程之间进行操作要注意ThreadLocal的传递,比较适合类似某个方法通过只读库进行select的操作,减轻读写库操作压力
代码参考:https://gitee.com/constfafa/spring_springboot_learning/tree/master/springboot-aop-datasource
在1.4.x及2.0.0 spring boot环境下测试均OK
方案4:
类似ShardingPhere等中间件,就比较重量级了