springboot 之 根据传入参数进行多数据源动态切换
背景:最近有一个需求是根据app传来的请求参数,根据行政部门编码请求不同地区的数据,之前写的多数据源都是固定某个方法调用指定的dao然后查询不同的数据库,但是这次是需要根据前端传入参数进行动态区分数据库,所以就需要做特殊处理
1.注册多数据源:
@Configuration
public class DataSourceConfiguration { /**
* 交管局数据源
*/
@Bean(name = "jiaoguanjuDataSource")
@Qualifier("jiaoguanjuDataSource")
@ConfigurationProperties(prefix="spring.datasource.jiaoguanju")
public DataSource jiaoguanjuDataSource() {
return DataSourceBuilder.create().build();
} /**
* 广州数据源
*/
@Bean(name = "guangzhouDataSource")
@Qualifier("guangzhouDataSource")
@ConfigurationProperties(prefix="spring.datasource.guangzhou")
public DataSource guangzhouDataSource() {
return DataSourceBuilder.create().build();
}
/**
* 清远数据源
*/
@Bean(name = "qingyuanDataSource")
@Qualifier("qingyuanDataSource")
@ConfigurationProperties(prefix="spring.datasource.qingyuan")
public DataSource qingyuanDataSource() {
return DataSourceBuilder.create().build();
} /**
* 韶关数据源
*/
@Bean(name = "shaoguanDataSource")
@Qualifier("shaoguanDataSource")
@ConfigurationProperties(prefix="spring.datasource.shaoguan")
public DataSource shaoguanDataSource() {
return DataSourceBuilder.create().build();
} /**
* cancl数据源
*/
@Bean(name = "secondaryDataSource")
@Qualifier("secondaryDataSource")
@ConfigurationProperties(prefix="spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
} @Bean(name = "dynamicDataSource")
@Primary
public DataSource dynamicDataSource(){
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.myMap = new HashMap<>();//保存我们有的数据源,方便后面动态增加
dynamicDataSource.myMap.put("guangzhou",guangzhouDataSource());
dynamicDataSource.myMap.put("qingyuan",qingyuanDataSource());
dynamicDataSource.myMap.put("shaoguan",shaoguanDataSource());
dynamicDataSource.myMap.put("jiaoguanju", jiaoguanjuDataSource());
// dynamicDataSource.myMap.put("3",thirdDataSource());
dynamicDataSource.setTargetDataSources(dynamicDataSource.myMap);//父类的方法
DynamicDataSourceContextHolder.dataSourceIds.addAll(dynamicDataSource.myMap.keySet());
dynamicDataSource.setDefaultTargetDataSource(guangzhouDataSource());//父类的方法
return dynamicDataSource;
} }
2.将数据源交给AbstractRoutingDataSource
/**
* @Author Cheng ZhiHua
* @Date 2019-11-05 16:01
* @Description 核心方法 :继承AbstractRoutingDataSource 类,将数据源交给AbstractRoutingDataSource进行注入使用
**/
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource { public Map<Object,Object> myMap = null; @Override
protected Object determineCurrentLookupKey() {
/*
* DynamicDataSourceContextHolder代码中使用setDataSourceType
* 设置当前的数据源,在路由类中使用getDataSourceType进行获取,
* 交给AbstractRoutingDataSource进行注入使用。
*/
// log.info("数据源为: {}",DynamicDataSourceContextHolder.getDataSourceType());
return DynamicDataSourceContextHolder.getDataSourceType(); } }
3.每个请求与线程绑定,保证各个请求之前互不影响
/**
* @Author Cheng ZhiHua
* @Date 2019-11-05 16:02
* @Description
**/
public class DynamicDataSourceContextHolder {
/* * 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本, * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 */ private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static List<Object> dataSourceIds = new ArrayList<Object>(); public static void setDataSourceType(String dataSourceType) { contextHolder.set(dataSourceType); } public static String getDataSourceType() { return contextHolder.get(); } public static void clearDataSourceType() { contextHolder.remove(); } public static boolean containsDataSource(String dataSourceId) { return dataSourceIds.contains(dataSourceId); } }
4.调用一定要在事务之前,在controller层
/**
* 设置当前线程的数据库连接
*
* @param data
*/
private void ThreadLocalParamSet(Map<String, Object> data) {
Map<String, String> userInfo = (Map<String, String>) data.get("userInfo");
String dataSourceType =
deptnoReleaseDatasourceMap.get(userInfo.get("userDeptNo").substring(0, 4));
DynamicDataSourceContextHolder.setDataSourceType(dataSourceType);
}
springboot 之 根据传入参数进行多数据源动态切换的更多相关文章
- springboot多数据源动态切换和自定义mybatis分页插件
1.配置多数据源 增加druid依赖 完整pom文件 数据源配置文件 route.datasource.driver-class-name= com.mysql.jdbc.Driver route.d ...
- Springboot多数据源配置--数据源动态切换
在上一篇我们介绍了多数据源,但是我们会发现在实际中我们很少直接获取数据源对象进行操作,我们常用的是jdbcTemplate或者是jpa进行操作数据库.那么这一节我们将要介绍怎么进行多数据源动态切换.添 ...
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源方法
一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...
- Spring多数据源动态切换
title: Spring多数据源动态切换 date: 2019-11-27 categories: Java Spring tags: 数据源 typora-root-url: ...... --- ...
- mybatis 多数据源动态切换
笔者主要从事c#开发,近期因为项目需要,搭建了一套spring-cloud微服务框架,集成了eureka服务注册中心. gateway网关过滤.admin服务监控.auth授权体系验证,集成了redi ...
- 实战:Spring AOP实现多数据源动态切换
需求背景 去年底,公司项目有一个需求中有个接口需要用到平台.算法.大数据等三个不同数据库的数据进行计算.组装以及最后的展示,当时这个需求是另一个老同事在做,我只是负责自己的部分. 直到今年回来了,这个 ...
- SpringBoot多数据源动态切换数据源
1.配置多数据源 spring: datasource: master: password: erp_test@abc url: jdbc:mysql://127.0.0.1:3306/M201911 ...
- SpringBoot之多数据源动态切换数据源
原文:https://www.jianshu.com/p/cac4759b2684 实现 1.建库建表 首先,我们在本地新建三个数据库名分别为master,slave1,slave2,我们的目前就是写 ...
随机推荐
- jchdl - GSL实例 - Register
https://mp.weixin.qq.com/s/uD5JVlAjTHQus2pnzPrdLg 多个D触发器可以组成一组寄存器. 摘自康华光<电子技术基础 · 数字部分>(第 ...
- Javascript中target事件属性,事件的目标节点的获取。
window.event.srcElement与window.event.target 都是指向触发事件的元素,它是什么就有什么样的属性 srcElement是事件初始化目标html元素对象引用,因为 ...
- Vue父子组件传值以及父调子方法、子调父方法
稍微总结了一下Vue中父子间传值以及相互调方法的问题,非常基础.希望可以帮到你!先来个最常用的,直接上代码: 1.父传值给子组件 父组件: <template> <div> & ...
- Java实现 蓝桥杯 算法提高 歌唱比赛(暴力)
试题 算法提高 歌唱比赛 问题描述 X市正在进行歌唱比赛,请你写一个程序计算得分. 每名选手从1到N编号,每名选手的综合成绩由以下几个部分组成: 1.歌唱得分占70% 2.才艺展示得分占20% 3.观 ...
- Java实现 LeetCode 611 有效三角形的个数(双指针)
611. 有效三角形的个数 给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数. 示例 1: 输入: [2,2,3,4] 输出: 3 解释: 有效的组合是: 2,3,4 ( ...
- Java实现 蓝桥杯VIP 算法训练 整除问题
问题描述 编写一个程序,输入三个正整数min.max和factor,然后对于min到max之间的每一个整数(包括min和max),如果它能被factor整除,就把它打印出来. 输入格式:输入只有一行, ...
- Java实现 蓝桥杯VIP 算法提高 乘法运算
算法提高 乘法运算 时间限制:1.0s 内存限制:512.0MB 问题描述 编制一个乘法运算的程序. 从键盘读入2个100以内的正整数,进行乘法运算并以竖式输出. 输入格式 输入只有一行,是两个用空格 ...
- java实现 蓝桥杯 算法训练 安慰奶牛
问题描述 Farmer John变得非常懒,他不想再继续维护供奶牛之间供通行的道路.道路被用来连接N个牧场,牧场被连续地编号为1到N.每一个牧场都是一个奶牛的家.FJ计划除去P条道路中尽可能多的道路, ...
- 用my eclipse 新建hibernate 第一个程序
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. 今天就来开始建我们的第一个hibernat ...
- 1.react的基础
1.react:专注于UI得一个js库 2.选择使用框架得原因: 写起来简单方便了,但是从稳定性上考虑得话还是原生js要稳定,所以也有很多公司直接使用原生js,但是从开发周期上来说时间会长 之前再写页 ...