东莞网站建设哪家专业/软文推广文案
前言
随着业务数据越来越多,多数据源和读写分离逐渐成为常规操作。可以给每个数据源写一套dao,这样代码很难维护,并且如果数据源太多,代码量恐怖的难以想象
办法
我们可以借助spring提供的扩展类AbstractRoutingDataSource实现,源码见 https://gitee.com/jauking/mybatis_demo
实现细节
AbstractRoutingDataSource 数据源路由
实现如项目中 com.example.mybatis_demo.datasource.DynamicDatasource
这个类是spring提供的数据源路由器,原理是我们构造一个多数据源的map,key是我们自己定义的任意类型,value是数据源,然后我们实现determineCurrentLookupKey方法,返回key。那spring需要数据源的时候会调用determineCurrentLookupKey方法返回key,然后从map中获取对应的数据源。那这个key怎么获取呢?
获取数据源的key
实现如项目中 com.example.mybatis_demo.datasource.DynamicDataSourceContextHolder
因为每次运行都在一个线程中,所以我们可以使用ThreadLocal保存和获取key。DynamicDatasource获取key没有问题,那什么时候set呢
setKey
setKey必须在调用框架getConnection之前,我们可以使用SpringAOP技术,拦截Service方法,在调用方法前,根据入参生成key,放到DynamicDataSourceContextHolder中。这样虽然可以,但是如果有多个地方使用了dao,那是不是需要代理多个地方,不是很方便。
本项目用到了mybatis,所以可以使用mubatis的拦截器,在query之前setKey,(如:com.example.mybatis_demo.datasource.MybatisDatasourceInterceptor)。
有了拦截器,我们要把拦截器放到容器中,如:com.example.mybatis_demo.config.MybatisInterceptorsConfig
其他
需要说明的是,本项目使用User.shardFlag属性作为切分键,实现分库分表。
那么如果需要实现读写分离的话,小伙伴们可以自己想想,如果有需要可以留言
完结
至此多数据源我们就实现了