AbstractRoutingDataSource

AbstractRoutingDataSource是spring-jdbc包提供的一个了AbstractDataSource的抽象类,它实现了DataSource接口的用于获取数据库连接的方法。下面是其源码:

 @Override public Connection getConnection() throws SQLException { return determineTargetDataSource().getConnection(); } @Override public Connection getConnection(String username, String password) throws SQLException { return determineTargetDataSource().getConnection(username, password); } protected DataSource determineTargetDataSource() { Assert.notNull(this.resolvedDataSources, "DataSource router not initialized"); // 获取指定数据源关键字 Object lookupKey = determineCurrentLookupKey(); DataSource dataSource = this.resolvedDataSources.get(lookupKey); if (dataSource == null && (this.lenientFallback || lookupKey == null)) { dataSource = this.resolvedDefaultDataSource; } if (dataSource == null) { throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]"); } return dataSource; } public void setTargetDataSources(Map targetDataSources) { this.targetDataSources = targetDataSources; }

可以看出,其数据源之间的切换主要 determineTargetDataSource()方法决定,其维护了一个名为targetDataSources的Map,并提供set方法,决定其具体从哪个数据源中获取链接;

下面,我们来看下具体实现代码:

1、先看数据库:

此处,我们有两个数据库,分别是cookie和cxq,其内部皆存在一张结构相同的user表,查看出数据如图:

2、配置文件 application.yml:

server : port : 9001spring : datasource: primary : jdbc-url: jdbc:mysql://xxx:82/cookie?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&useSSL=false username: root password: xxx driver-class-name: com.mysql.cj.jdbc.Driver second : jdbc-url: jdbc:mysql://xxx:82/cxq?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&useSSL=false username: root password: xxx driver-class-name: com.mysql.cj.jdbc.Drivermybatis: type-aliases-package: com.cookie.modellogging: level: root: INFO org.hibernate: INFO org.hibernate.type.descriptor.sql.BasicBinder: TRACE org.hibernate.type.descriptor.sql.BasicExtractor: TRACE com.itmuch.youran.persistence: ERROR

3、新建 DataSourceContextHolder,配置数据源

package com.cookie;/** * author : cxq * Date : 2019/5/15 */public class DataSourceContextHolder { /** * 默认数据源 */ public static final String primaryDataSource = "primaryDataSource"; public static final String secondDataSource = "secondDataSource"; // 使用ThreadLocal 可以有效避免多线程时contextHolder被更改,导致访问出错的问题 // 每一个ThreadLocal能够放一个线程级别的变量,可是它本身能够被多个线程共享使用,并且又能够达到线程安全的目的,且绝对线程安全 private static final ThreadLocal contextHolder = new ThreadLocal<>(); // 设置数据源名 public static void setDB(String dbType) { contextHolder.set(dbType); } // 获取数据源名 public static String getDB() { return (contextHolder.get()); } // 清除数据源名 public static void clearDB() { contextHolder.remove(); }}

4、新建DynamicDataSource

package com.cookie;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/** * author : cxq * Date : 2019/5/15 */public class DynamicDataSource extends AbstractRoutingDataSource { private final static Logger logger = LoggerFactory.getLogger(DynamicDataSource.class); @Override protected Object determineCurrentLookupKey() { logger.info(" datasource : " + ( DataSourceContextHolder.getDB() == null ? DataSourceContextHolder.secondDataSource : DataSourceContextHolder.getDB() ) ); return DataSourceContextHolder.getDB(); }}

该类继承了AbstractRoutingDataSource,重写determineCurrentLookupKey,在该方法中注入实际应用的dataSource,下面,我们需要创建bean;

5、配置bean

package com.cookie;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.boot.jdbc.DataSourceBuilder;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import org.springframework.jdbc.datasource.DataSourceTransactionManager;import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;import java.util.HashMap;import java.util.Map;/** * author : cxq * Date : 2019/5/15 */@Configurationpublic class CommonConfig { @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource (){ return DataSourceBuilder.create().build(); } @Bean(name = "secondDataSource") @ConfigurationProperties(prefix = "spring.datasource.second") public DataSource secondDataSource (){ return DataSourceBuilder.create().build(); } /** * 动态数据源 :通过AOP在不同数据源之间切换 * @return */ @Primary @Bean(name = "dynamicDataSource") public DataSource dynamicDataSource() { DynamicDataSource dynamicDataSource = new DynamicDataSource(); // 默认数据源 dynamicDataSource.setDefaultTargetDataSource(secondDataSource()); // 配置多数据源 Map dsMap = new HashMap<>(); dsMap.put("primaryDataSource

springboot动态切换数据源_Springboot整合Mybatis注解实现动态数据源切换相关推荐

  1. Spring Boot 入门系列(二十三)整合Mybatis,实现多数据源配置!

    d之前介绍了Spring Boot 整合mybatis 使用注解方式配置的方式实现增删改查以及一些复杂自定义的sql 语句 .想必大家对spring boot 项目中,如何使用mybatis 有了一定 ...

  2. mybatis java类注解式_Spring整合Mybatis注解方式

    Spring整合Mybatis(注解方式) 环境准备 jar包: Spring所需依赖:spring-context.spring-aspects.aspectjrt.aspectjweaver.sp ...

  3. mybatis注解开发动态sql

    mybatis注解开发动态sql 本篇来讲一下如何使用mybatis注解模式中的动态sql 先来讲一下什么是动态sql 在我们实际开发的时候可能会出现很多方法需要一条很相似的sql语句来进行增删改查, ...

  4. Mybatis 注解开发 + 动态SQL

    Hello 大家好我是橙子同学,今天分享注解Mybatis注解开发+动态sql 目录 每文一铺垫(今天有小插曲哦) 注解开发 添加 @Insert 删除 @Delete 查询 @Select 修改 @ ...

  5. mysql动态配置数据源_Spring整合Mybatis实现动态数据源切换教程配置

    一.摘要 这篇文章将介绍Spring整合Mybatis 如何完成SqlSessionFactory的动态切换的.并且会简单的介绍下MyBatis整合Spring中的官方的相关代码. Spring整合M ...

  6. springboot update数据_SpringBoot整合Mybatis+Druid+数据库(注解版)

    运行展示 正题 Spring boot :2.1.5RELEASE :数据库(Mysql.Oracle):Mybatis:阿里云的连接池 : Druid : 步骤 1.POM依赖 <!-- My ...

  7. springboot 多数据源_SpringBoot整合多数据源的巨坑一

    导读 本篇文章接上篇SpringBoot整合多数据源,你会了吗?,前面文章最后留了几个问题供大家思考,今天一一揭晓. 配置如何优化 上文整合的过程中的还顺带整合Mybatis和TransactionM ...

  8. Spring Boot多数据源配置并通过注解实现动态切换数据源

    文章目录 1. AbstractRoutingDataSource类介绍 2. ThreadLocal类介绍 3. 环境准备 3.1 数据库准备 3.2 项目创建 4. 具体实现 4.1 定义数据源枚 ...

  9. springboot 引入jdbc驱动_SpringBoot整合jdbc、durid、mybatis详解,数据库的连接就是这么简单...

    SpringBoot底层统一采用SpringData处理数据库,这一章主要来讲一下SpringBoot整合jdbc.durid.mybatis的方式. (一)整合jdbc 整合jdbc主要有三步: 1 ...

最新文章

  1. ubuntu 内存占用解析
  2. 数据可视化项目落地复盘
  3. 一文读懂云上用户如何灵活应用定制化网络服务
  4. yelee主题博客四周变透明
  5. 【转】Wireshark网络抓包(二)——过滤器
  6. SSH远程登录失败,提示“Password authentication failed”
  7. eclipse创建springboot项目的三种方法
  8. oracle解压后不能运行,求救:oracle10安装后net Manager等工具无法启动
  9. java三大特性(封装、继承、多态)
  10. hiho一下 第二十九周 最小生成树三·堆优化的Prim算法【14年寒假弄了好长时间没搞懂的prim优化:prim算法+堆优化 】...
  11. python樱花_如何基于python实现画不同品种的樱花树
  12. 微信小程序,video 全屏视屏展示,广告样式
  13. yolov5 行人 车辆 跟踪 检测 计数
  14. switch怎么一个账号绑定各种服务器,NS怎么一个账号两台机器使用_Nintendo Switch 新旧机器同使用教程_尼萌手游网...
  15. fsf大流行政治天网抗议监视
  16. 设置 Scite编辑器的默认编辑为 UTF-8 ,及其他一些参数配置
  17. 通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core? 转自:https://www.cnblogs.com/1996V/p/9037603.html#net1...
  18. linux 从samba拷贝,提升samba复制速度,树莓派外接硬盘读取从40M到110M(2020-11-15更新)...
  19. 【Linux】必须掌握的Linux常见指令分类讲解
  20. An unexpected error has been detected by Java Runtime Environment

热门文章

  1. C++ String16与const char*及char*与vector相互转换
  2. Android TextureView简易教程
  3. linux fuse文件系统在 android fuse sdcard的 运用
  4. SDWebImage获取到UIImage分辨率跟原图不一样
  5. tensorflow之线性回归
  6. ipv6单播地址包括哪两种类型_探秘联接|技术小课堂之BRAS设备IPv6地址分配方式...
  7. 如何求地球上两点之间的最短距离_高三数学这样复习“最高效”,稳稳120+!...
  8. 如何远程登录连接Linux云服务器(电脑端/移动端)?
  9. 地图样式自定义_用地图做数据分析,地图可视化更显高级
  10. ngrok 代理访问