最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
spring实现动态切换、添加数据源及源码分析
时间:2018-09-17 编辑:猪哥 来源:一聚教程网
前言
对于数据量在1千万,单个mysql数据库就可以支持,但是如果数据量大于这个数的时候,例如1亿,那么查询的性能就会很低。此时需要对数据库做水平切分,常见的做法是按照用户的账号进行hash,然后选择对应的数据库。
最近公司项目需求,由于要兼容老系统的数据库结构,需要搭建一个 可以动态切换、添加数据源的后端服务。
参考了过去的项目,通过配置多个SqlSessionFactory 来实现多数据源,这么做的话,未免过于笨重,而且无法实现动态添加数据源这个需求
通过 spring AbstractRoutingDataSource 为我们抽象了一个 DynamicDataSource 解决这一问题
简单分析下 AbstractRoutingDataSource 的源码
targetDataSources 就是我们的多个数据源,在初始化的时候会调用afterPropertiesSet(),去解析我们的数据源 然后 put 到 resolvedDataSources
实现了 DataSource 的 getConnection(); 我们看看 determineTargetDataSource(); 做了什么
通过下面的 determineCurrentLookupKey();(这个方法需要我们实现) 返回一个key,然后从 resolvedDataSources (其实也就是 targetDataSources) 中 get 一个数据源,实现了每次调用 getConnection(); 打开连接 切换数据源,如果想动态添加的话 只需要重新 set targetDataSources 再调用 afterPropertiesSet() 即可
Talk is cheap. Show me the code
我使用的springboot版本为 1.5.x,下面是核心代码
完整代码:https://gitee.com/yintianwen7/spring-dynamic-datasource (本地下载)
/** * 多数据源配置 * * @author Taven * */ @Configuration @MapperScan("com.gitee.taven.mapper") public class DataSourceConfigurer { /** * DataSource 自动配置并注册 * * @return data source */ @Bean("db0") @Primary @ConfigurationProperties(prefix = "datasource.db0") public DataSource dataSource0() { return DruidDataSourceBuilder.create().build(); } /** * DataSource 自动配置并注册 * * @return data source */ @Bean("db1") @ConfigurationProperties(prefix = "datasource.db1") public DataSource dataSource1() { return DruidDataSourceBuilder.create().build(); } /** * 注册动态数据源 * * @return */ @Bean("dynamicDataSource") public DataSource dynamicDataSource() { DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource(); Map
通过 ThreadLocal 获取线程安全的数据源 key
package com.gitee.taven.config; public class DynamicDataSourceContextHolder { private static final ThreadLocalcontextHolder = new ThreadLocal () { @Override protected String initialValue() { return "dynamic_db0"; } }; /** * To switch DataSource * * @param key the key */ public static void setDataSourceKey(String key) { contextHolder.set(key); } /** * Get current DataSource * * @return data source key */ public static String getDataSourceKey() { return contextHolder.get(); } /** * To set DataSource as default */ public static void clearDataSourceKey() { contextHolder.remove(); } }
动态 添加、切换数据源
/** * 动态数据源 * * @author Taven * */ public class DynamicRoutingDataSource extends AbstractRoutingDataSource { private final Logger logger = LoggerFactory.getLogger(getClass()); private static Map
可以通过 AOP 或者 手动 DynamicDataSourceContextHolder.setDataSourceKey(String key) 切换数据源
需要注意的:当我们开启了事务之后,是无法在去切换数据源的
本文项目源码:https://gitee.com/yintianwen7/spring-dynamic-datasource (本地下载)
参考文献:https://github.com/helloworlde/SpringBoot-DynamicDataSource
相关文章
- SpringBoot自定义bean绑定解析 10-24
- Javaweb工程运行报错HTTP Status 404解决教程 10-20
- JAVA获取jvm和操作系统相关信息方法 10-20
- BeanFactory和FactoryBean的区别讲解 10-20
- 微信小程序的宿主环境实现教程 10-10
- dispatchEvent解决重叠元素响应事件教程 10-10