背景:最近有一个需求是根据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 之 根据传入参数进行多数据源动态切换的更多相关文章

  1. springboot多数据源动态切换和自定义mybatis分页插件

    1.配置多数据源 增加druid依赖 完整pom文件 数据源配置文件 route.datasource.driver-class-name= com.mysql.jdbc.Driver route.d ...

  2. Springboot多数据源配置--数据源动态切换

    在上一篇我们介绍了多数据源,但是我们会发现在实际中我们很少直接获取数据源对象进行操作,我们常用的是jdbcTemplate或者是jpa进行操作数据库.那么这一节我们将要介绍怎么进行多数据源动态切换.添 ...

  3. Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法

    一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...

  4. Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源方法

    一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...

  5. Spring多数据源动态切换

    title: Spring多数据源动态切换 date: 2019-11-27 categories: Java Spring tags: 数据源 typora-root-url: ...... --- ...

  6. mybatis 多数据源动态切换

    笔者主要从事c#开发,近期因为项目需要,搭建了一套spring-cloud微服务框架,集成了eureka服务注册中心. gateway网关过滤.admin服务监控.auth授权体系验证,集成了redi ...

  7. 实战:Spring AOP实现多数据源动态切换

    需求背景 去年底,公司项目有一个需求中有个接口需要用到平台.算法.大数据等三个不同数据库的数据进行计算.组装以及最后的展示,当时这个需求是另一个老同事在做,我只是负责自己的部分. 直到今年回来了,这个 ...

  8. SpringBoot多数据源动态切换数据源

    1.配置多数据源 spring: datasource: master: password: erp_test@abc url: jdbc:mysql://127.0.0.1:3306/M201911 ...

  9. SpringBoot之多数据源动态切换数据源

    原文:https://www.jianshu.com/p/cac4759b2684 实现 1.建库建表 首先,我们在本地新建三个数据库名分别为master,slave1,slave2,我们的目前就是写 ...

随机推荐

  1. jchdl - GSL实例 - Register

    https://mp.weixin.qq.com/s/uD5JVlAjTHQus2pnzPrdLg   多个D触发器可以组成一组寄存器. ​​ 摘自康华光<电子技术基础 · 数字部分>(第 ...

  2. Javascript中target事件属性,事件的目标节点的获取。

    window.event.srcElement与window.event.target 都是指向触发事件的元素,它是什么就有什么样的属性 srcElement是事件初始化目标html元素对象引用,因为 ...

  3. Vue父子组件传值以及父调子方法、子调父方法

    稍微总结了一下Vue中父子间传值以及相互调方法的问题,非常基础.希望可以帮到你!先来个最常用的,直接上代码: 1.父传值给子组件 父组件: <template> <div> & ...

  4. Java实现 蓝桥杯 算法提高 歌唱比赛(暴力)

    试题 算法提高 歌唱比赛 问题描述 X市正在进行歌唱比赛,请你写一个程序计算得分. 每名选手从1到N编号,每名选手的综合成绩由以下几个部分组成: 1.歌唱得分占70% 2.才艺展示得分占20% 3.观 ...

  5. Java实现 LeetCode 611 有效三角形的个数(双指针)

    611. 有效三角形的个数 给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数. 示例 1: 输入: [2,2,3,4] 输出: 3 解释: 有效的组合是: 2,3,4 ( ...

  6. Java实现 蓝桥杯VIP 算法训练 整除问题

    问题描述 编写一个程序,输入三个正整数min.max和factor,然后对于min到max之间的每一个整数(包括min和max),如果它能被factor整除,就把它打印出来. 输入格式:输入只有一行, ...

  7. Java实现 蓝桥杯VIP 算法提高 乘法运算

    算法提高 乘法运算 时间限制:1.0s 内存限制:512.0MB 问题描述 编制一个乘法运算的程序. 从键盘读入2个100以内的正整数,进行乘法运算并以竖式输出. 输入格式 输入只有一行,是两个用空格 ...

  8. java实现 蓝桥杯 算法训练 安慰奶牛

    问题描述 Farmer John变得非常懒,他不想再继续维护供奶牛之间供通行的道路.道路被用来连接N个牧场,牧场被连续地编号为1到N.每一个牧场都是一个奶牛的家.FJ计划除去P条道路中尽可能多的道路, ...

  9. 用my eclipse 新建hibernate 第一个程序

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. 今天就来开始建我们的第一个hibernat ...

  10. 1.react的基础

    1.react:专注于UI得一个js库 2.选择使用框架得原因: 写起来简单方便了,但是从稳定性上考虑得话还是原生js要稳定,所以也有很多公司直接使用原生js,但是从开发周期上来说时间会长 之前再写页 ...