Spring多数据源配置以及动态切换实现

  • 问题描述
    • 一:首先是配置数据源
      • 1、使用xml的bean节点来配置
      • 2、使用yml配置+java代码实现配置
    • 二:动态数据源
    • 三:使用AOP切面实现动态数据源的切换

问题描述

 这篇文章主要是结合自己的经验,总结下多数据源配置实现的方式!

一:首先是配置数据源

1、使用xml的bean节点来配置

<bean id="dataSource"class="com.framework.datasourceRoute.DynamicDataSource"><property name="targetDataSources"><map><entry key="master" value-ref="master"></entry><entry key="slave" value-ref="slave"></entry></map></property><property name="defaultTargetDataSource" ref="master"></property></bean><bean id="master" class="com.alibaba.druid.pool.DruidDataSource"destroy-method="close"><property name="url" value="${master.ds.jdbcUrl}" /><property name="username" value="${master.ds.user}" /><!-- <property name="password" value="${master.ds.password}" /> --><property name="password" value="DB.mring-coop.PassWord" /><property name="initialSize" value="${master.ds.initialSize}" /><property name="minIdle" value="${master.ds.minIdle}" /><property name="maxActive" value="${master.ds.maxActive}" /><property name="maxWait" value="${master.ds.maxWait}" /><property name="timeBetweenEvictionRunsMillis" value="${master.ds.timeBetweenEvictionRunsMillis}" /><property name="minEvictableIdleTimeMillis" value="${master.ds.minEvictableIdleTimeMillis}" /><property name="validationQuery" value="${master.ds.validationQuery}" /><property name="testWhileIdle" value="${master.ds.testWhileIdle}" /><property name="testOnBorrow" value="${master.ds.testOnBorrow}" /><property name="testOnReturn" value="${master.ds.testOnReturn}" /></bean><bean id="slave" class="com.alibaba.druid.pool.DruidDataSource"destroy-method="close"><property name="url" value="${slave.ds.jdbcUrl}" /><property name="username" value="${slave.ds.user}" /><property name="password" value="${slave.ds.password}" /><property name="initialSize" value="${slave.ds.initialSize}" /><property name="minIdle" value="${slave.ds.minIdle}" /><property name="maxActive" value="${slave.ds.maxActive}" /><property name="maxWait" value="${slave.ds.maxWait}" /><property name="timeBetweenEvictionRunsMillis" value="${slave.ds.timeBetweenEvictionRunsMillis}" /><property name="minEvictableIdleTimeMillis" value="${slave.ds.minEvictableIdleTimeMillis}" /><property name="validationQuery" value="${slave.ds.validationQuery}" /><property name="testWhileIdle" value="${slave.ds.testWhileIdle}" /><property name="testOnBorrow" value="${slave.ds.testOnBorrow}" /><property name="testOnReturn" value="${slave.ds.testOnReturn}" /></bean>

2、使用yml配置+java代码实现配置

application.yml

# 数据源配置  开发库
spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedruid:# 主库数据源master:url: jdbc:mysql://localhost:3309/dtp?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: xxpassword: 123# 从库数据源crm:driverClassName: oracle.jdbc.OracleDriverenabled: trueurl: jdbc:oracle:thin:@localhost:1521:OADBusername: xxpassword: 123# 初始连接数initialSize: 5# 最小连接池数量minIdle: 10# 最大连接池数量maxActive: 20# 配置获取连接等待超时的时间maxWait: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒timeBetweenEvictionRunsMillis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒minEvictableIdleTimeMillis: 300000# 配置一个连接在池中最大生存的时间,单位是毫秒maxEvictableIdleTimeMillis: 900000# 配置检测连接是否有效validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsewebStatFilter: enabled: truestatViewServlet:enabled: true# 设置白名单,不填则允许所有访问allow:url-pattern: /monitor/druid/*filter:stat:enabled: true# 慢SQL记录log-slow-sql: trueslow-sql-millis: 1000merge-sql: truewall:config:multi-statement-allow: true

DataSourceConfig.java

package com.lbx.framework.config;import java.util.HashMap;
import java.util.Map;import javax.sql.DataSource;import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.lbx.common.enums.DataSourceType;
import com.lbx.framework.config.properties.DruidProperties;
import com.lbx.framework.datasource.DynamicDataSource;/*** druid 配置多数据源* * @author ruoyi*/
@Configuration
public class DruidConfig {@Bean@ConfigurationProperties("spring.datasource.druid.master")public DataSource masterDataSource(DruidProperties druidProperties) {DruidDataSource dataSource = DruidDataSourceBuilder.create().build();return druidProperties.dataSource(dataSource);}@Bean@ConfigurationProperties("spring.datasource.druid.crm")@ConditionalOnProperty(prefix = "spring.datasource.druid.crm", name = "enabled", havingValue = "true")public DataSource crmDataSource(DruidProperties druidProperties) {DruidDataSource dataSource = DruidDataSourceBuilder.create().build();return druidProperties.dataSource(dataSource);}@Bean(name = "dynamicDataSource")@Primarypublic DynamicDataSource dataSource(DataSource masterDataSource, DataSource crmDataSource) {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);targetDataSources.put(DataSourceType.CRM.name(), crmDataSource);return new DynamicDataSource(masterDataSource, targetDataSources);}
}

二:动态数据源

DynamicDataSource.java

/*** 动态数据源* * @author ruoyi*/
public class DynamicDataSource extends AbstractRoutingDataSource
{public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources){super.setDefaultTargetDataSource(defaultTargetDataSource);super.setTargetDataSources(targetDataSources);super.afterPropertiesSet();}/*** 方法内就是数据源切换的规则,可以自定义*/@Overrideprotected Object determineCurrentLookupKey(){return DynamicDataSourceSwitch.getDateSoureType();}
}

DynamicDataSourceSwitch.java


/*** 数据源切换处理* * @author ruoyi*/
public class DynamicDataSourceSwitch
{public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceSwitch.class);/*** 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,*  所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。*/private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();/*** 设置数据源的变量*/public static void setDateSoureType(String dsType){log.info("切换到{}数据源", dsType);CONTEXT_HOLDER.set(dsType);}/*** 获得数据源的变量*/public static String getDateSoureType(){return CONTEXT_HOLDER.get();}/*** 清空数据源变量*/public static void clearDateSoureType(){CONTEXT_HOLDER.remove();}

三:使用AOP切面实现动态数据源的切换


/*** 多数据源处理* * @author ruoyi*/
@Aspect
@Order(1)
@Component
public class DataSourceAspect
{protected Logger logger = LoggerFactory.getLogger(getClass());@Pointcut("@annotation(com.lbx.common.annotation.DataSource)")public void dsPointCut(){}@Around("dsPointCut()")public Object around(ProceedingJoinPoint point) throws Throwable{MethodSignature signature = (MethodSignature) point.getSignature();Method method = signature.getMethod();DataSource dataSource = method.getAnnotation(DataSource.class);if (StringUtils.isNotNull(dataSource)){DynamicDataSourceContextSwitch.setDateSoureType(dataSource.value().name());}try{return point.proceed();}finally{// 销毁数据源 在执行方法之后DynamicDataSourceContextSwitch.clearDateSoureType();}}
}

上面是使用切面+注解来实现自定义数据源的切换的,还有一种比AOP笨的方法,就是直接中使用Dao之前,通过代码手工切换数据源,如DynamicDataSourceSwitch.setDataSource(“slave”)。

好啦,今天的学习就到这里啦。。

Spring多数据源配置以及动态切换实现相关推荐

  1. 搭建eclipse版的ssm+maven+tk.mybatis+redis及mybatis+spring多数据源配置集成的demo

    前言:我这里搭建好eclipse版的ssm+maven+tk.mybatis+redis及mybatis+spring多数据源配置集成的demo.新手快速上手直接看demo. 最后处提供完整高质量de ...

  2. java spring多数据源配置文件_深入理解spring多数据源配置

    项目中我们经常会遇到多数据源的问题,尤其是数据同步或定时任务等项目更是如此.多数据源让人最头痛的,不是配置多个数据源,而是如何能灵活动态的切换数据源.例如在一个spring和hibernate的框架的 ...

  3. Spring多数据源配置

    Spring多数据源配置,这里持久层框架使用mybatis,集成Mybatis多数据源有两种方式: 1.创建多个SqlSessionFactory,扫描每个SqlSessionFactoryBean对 ...

  4. SpringBoot2/SpringBoot/Java动态数据源配置、动态连接池配置、多数据源负载均衡

    Java动态数据源配置.动态连接池配置.多数据源负载均衡 大家好,今天给大家推荐一个自产的连接池插件.废话不多说,本文接口分为以下主题: 1. 插件开发背景: 2. 插件提供的能力: 3. 插件的使用 ...

  5. springBoot学习(二)配置环境动态切换和部分注解的运用

    springBoot配置环境动态切换 建立第一个配置文件(springBoot默认读取的文件)application.properties test.name=default test.default ...

  6. Spring多数据源配置和使用

    Spring多数据源配置和使用 1.配置信息 <!--==============================bpt_mobdb数据库配置========================== ...

  7. spring(16)------spring的数据源配置

    spring(16)------spring的数据源配置 在spring中,通过XML的形式实现数据源的注入有三种形式. 一.使用spring自带的DriverManagerDataSource 使用 ...

  8. Spring自定义数据源配置不当引起的Mybatis拦截器Interceptors 失效/不生效

    目录 内容 Interceptor接口与@Intercepts注解 PageHelper实现拦截器 默认数据源与拦截器 自定义数据源与拦截器的问题 自定义数据源注入拦截器 内容 Interceptor ...

  9. Spring 多数据源配置详解

    前言 数据源是 JDBC 规范中用来获取关系型数据库连接的一个接口,主要通过池化技术来复用连接. 简单点的 Java 项目或者拆分比较彻底的微服务模块中只会用到一个数据库实例,对应一个数据源.稍复杂点 ...

最新文章

  1. Luogu P4859「已经没有什么好害怕的了」
  2. [原]LVM管理问题解决
  3. python 生成时间序列
  4. 如何通过Keil将程序正确的下载进flash中
  5. 路易斯安那州立大学计算机科学,西北路易斯安那州立大学
  6. 不同的编译器:GCC G++ C C++的区别
  7. 使用VS Code从零开始开发调试.NET Core 1.1
  8. linux 复制分区文件,dd复制分区后目标分区的大小变成原分区了
  9. WebService中文件传输
  10. 修复MacBook Touch Bar(触控栏)无法正常工作的方法
  11. Kinetic使用注意点--circle
  12. 190726每日一句
  13. 制作双色调图像(RGB 颜色模式)
  14. 斯蒂文斯理工学院计算机科学硕士,2020年斯蒂文斯理工学院排名TFE Times美国最佳计算机科学硕士专业排名第80...
  15. UT000010: Session is invalid
  16. okvis 基于关键帧视觉惯性传感器非线性优化SLAM 论文翻译+博客总结
  17. windows保护无法启动修复服务器,命令修复Win10系统提示Windows 资源保护无法启动修复服务的解决方法...
  18. iscc 2021wp
  19. 网络信号浪涌防雷器的应用
  20. plotwidget横坐标日期_求助x轴为日期时间的图形绘制

热门文章

  1. 携程Java面试题,疯狂java讲义第三版
  2. 电脑花屏是屏幕坏了吗_电脑花屏时好时坏怎么回事 电脑花屏时好时坏如何彻底解决...
  3. 计算机高考怎么复习,高考倒计时30天,清北学霸倾情传授高效复习秘籍
  4. 如何连接MySQL数据库
  5. php会计科目,ThinkPHP+EasyUI之ComboTree中的会计科目树形菜单实现方法
  6. 戴尔科技全面创新,让数字化梦想照见现实
  7. [论文速览]:Multi-source Domain Adaptation for Semantic Segmentation
  8. 百度上湖南卫视招聘 李彦宏展现舞技
  9. 帝国cms7.5《非小号》源码 区块链模板 行情数据+同步插件
  10. Stratifyd报告解读:大数据之下的定制家居消费体验洞察