AbstractRoutingDataSource - 动态数据源
AbstractRoutingDataSource 类说明:
(1)它的抽象方法 determineCurrentLookupKey() 决定使用哪个数据源。
(2)项目启动时,先调用 setTargetDataSources() 方法,然后框架调用 afterPropertiesSet() 方法。
后续需要实时刷新数据源时,需要手动调用以上两个方法!
(3)我们手动提交给 setTargetDataSources 方法的是用来初始化 targetDataSources 的入参,一个 Map<Stirng, DataSource> 结构的对象。但是执行数据库操作时,是从 resolvedDataSources 对象中获取数据源的,afterPropertiesSet() 方法就是用来初始化后者的!
DataSourceContextHolder-切换数据源
public class DynamicDataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setDataSourceKey(String key) {
contextHolder.set(key);
}
public static String getDataSourceKey() {
return contextHolder.get();
}
public static void clearDataSourceKey() {
contextHolder.remove();
}
}
RoutingDataSource - AbstractRoutingDataSource子类
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getDataSourceKey();
}
}
RoutingDataSourceConfig - 配置类
@Configuration
public class DynamicDataSourceConfig {
@Autowired
private DataSource dataSourceDefault;
@Autowired
private JdbcTemplate jdbcTemplate;
private DataSource createDataSource(Map<String, Object> map) {
DruidDecryptDataSource dataSource = new DruidDecryptDataSource();
dataSource.setDriverClassName(map.get("DRIVER_CLASS_NAME").toString());
dataSource.setUrl(map.get("URL").toString());
dataSource.setUsername(map.get("USERNAME").toString());
dataSource.setPassword(map.get("PASSWORD").toString());
dataSource.setMaxWait(10000);//10s
return dataSource;
}
public Map<Object, Object> dataSourceMap() {
List<Map<String, Object>> list = jdbcTemplate.queryForList("select * from dataSource");
Map<Object, Object> returnMap = new HashMap<Object, Object>();
for(Map<String, Object> map : list) {
returnMap.put(map.get("DATASOURCE_NAME"), createDataSource(map));
}
return returnMap;
}
@Bean("dataSource")
public DynamicDataSource dataSource() {
DynamicDataSource ddataSource = new DynamicDataSource();
ddataSource.setDefaultTargetDataSource(dataSourceDefault);// 设置默认数据源
ddataSource.setTargetDataSources(dataSourceMap());
return ddataSource;
}
@Bean("jdbcTemplate")
public NamedParameterJdbcTemplate jdbcTemplate(@Qualifier("dataSource") DynamicDataSource dataSource) {
return new NamedParameterJdbcTemplate(new JdbcTemplate(dataSource));
}
}
AbstractRoutingDataSource - 动态数据源的更多相关文章
- 【开发笔记】- AbstractRoutingDataSource动态数据源切换,AOP实现动态数据源切换
AbstractRoutingDataSource动态数据源切换 上周末,室友通宵达旦的敲代码处理他的多数据源的问题,搞的非常的紧张,也和我聊了聊天,大概的了解了他的业务的需求.一般的情况下我们都是使 ...
- AbstractRoutingDataSource动态数据源切换,AOP实现动态数据源切换
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/u012881904/article/de ...
- @Transactional导致AbstractRoutingDataSource动态数据源无法切换的解决办法
上午花了大半天排查一个多数据源主从切换的问题,记录一下: 背景: 项目的数据库采用了读写分离多数据源,采用AOP进行拦截,利用ThreadLocal及AbstractRoutingDataSource ...
- AbstractRoutingDataSource动态数据源切换
操作数据一般都是在DAO层进行处理,可以选择直接使用JDBC进行编程(http://blog.csdn.net/yanzi1225627/article/details/26950615/) 或者是使 ...
- @Transactional导致无法动态数据源切换
公司目前数据源为主从模式:主库可读写,从库只负责读.使用spring-jdbc提供的AbstractRoutingDataSource结合ThreadLocal存储key,实现数据源动态切换. 最近项 ...
- 43. Spring Boot动态数据源(多数据源自动切换)【从零开始学Spring Boot】
[视频&交流平台] àSpringBoot视频 http://study.163.com/course/introduction.htm?courseId=1004329008&utm ...
- Spring Boot 动态数据源(多数据源自己主动切换)
本文实现案例场景: 某系统除了须要从自己的主要数据库上读取和管理数据外.另一部分业务涉及到其它多个数据库,要求能够在不论什么方法上能够灵活指定详细要操作的数据库. 为了在开发中以最简单的方法使用,本文 ...
- (43). Spring Boot动态数据源(多数据源自动切换)【从零开始学Spring Boot】
在上一篇我们介绍了多数据源,但是我们会发现在实际中我们很少直接获取数据源对象进行操作,我们常用的是jdbcTemplate或者是jpa进行操作数据库.那么这一节我们将要介绍怎么进行多数据源动态切换.添 ...
- Spring Boot 动态数据源(Spring 注解数据源)
本文实现案例场景:某系统除了需要从自己的主要数据库上读取和管理数据外,还有一部分业务涉及到其他多个数据库,要求可以在任何方法上可以灵活指定具体要操作的数据库. 为了在开发中以最简单的方法使用,本文基于 ...
- Spring Boot:实现MyBatis动态数据源
综合概述 在很多具体应用场景中,我们需要用到动态数据源的情况,比如多租户的场景,系统登录时需要根据用户信息切换到用户对应的数据库.又比如业务A要访问A数据库,业务B要访问B数据库等,都可以使用动态数据 ...
随机推荐
- js 时间 日期
date.getYear(); // 获取当前年份(2 位) date.getFullYear(); // 获取完整的年份(4 位, 1970-????) date.getMonth(); // 获取 ...
- VUE学习-组件通信
vue组件通信 页面传值:$route/${prop} 组件传值: 父组件传值给子组件:参数传值 子组件传值给父组件:给父组件传过来函数传参数:通过插槽的v-slot,绑定参数 组件通信一般分为以下几 ...
- 2022-3-11内部群每日三题-清辉PMP
1.供应商通知项目经理可能延迟交付一个模块.项目经理应该怎么做? A.立即通知相关方. B.通过增加额外的天数来修改项目管理计划,并记录它们对项目时间的影响. C.审查风险管理计划以评估风险,然后通知 ...
- JS篇(003)-请用 js 去除字符串空格?
答案:replace 正则匹配方法.str.trim()方法.JQ 方法:$.trim(str)方法 解析: 方法一:replace 正则匹配方法 去除字符串内所有的空格:str = str.repl ...
- Ant Design 分页数据回显问题
我们可以创建一个新的值来保存这些数据allSingleSelectedRowKeys: 下面是我们的HTML结构 <a-table :row-selection="{ selected ...
- 【BOOK】解析库--pyquery
CSS选择器 1.初始化 html=''' <div> <ul> <li class="item-0">first item</li> ...
- nginx 添加ssl认证,访问静态资源 笔记
1.查看是否开启SSL模块, /usr/local/nginx/sbin ./nginx -V 2.没有开启,进入到nginx源码包目录下: 3编译 ./configure --prefix= ...
- 【LeetCode - 1055】形成字符串的最短路径
1.题目描述 代码: #include <iostream> #include <string> using namespace std; const int MAX_LETT ...
- windows jetbrains toolbox 无法修改应用安装目录(应用正在运行)的解决方案
打开 jetbrains toolbook安装目录/.settings.json 添加一行 "install_location": 指定的路径地址 解决方案来自 JetBrains ...
- 蓝桥2020 B组 第一场考试
2. 纪念日 问题描述: 请问从 1921 年 7 月 23 日中午 12 时到 2020 年 7 月 1 日中午 12 时一共包 含多少分钟? 答案提交: 这是一道结果填空题,你只需要算出结果后提交 ...