springboot配置多数据源
springboot配置多数据源
学习新技术,争做新青年,欢迎围观,河南老乡在上海请,加,微,andyfau2022,
----获取数据源:null,数据源为null时默认使用主数据源的。
1-yml文件
spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driverdruid:# 主库数据源master:url: jdbc:mysql:/306/andy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword:# 从库数据源slave:# 从数据源开关/默认关闭enabled: trueurl: jdbc:mysql/demo_project?useUnicode=true&characterEncodhavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: slave-aaa:# 从数据源开关/默认关闭enabled: true
# driverClassName: org.postgresql.Driverurl: jdbc:mysql:/_databaseuseUnicode=true&characterEncoding=utf8&avior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: # 初始连接数initialSize: 5# 最小连接池数量minIdle: 10# 最大连接池数量maxActive: 20# 配置获取连接等待超时的时间maxWait: 60000# 配置连接超时时间connectTimeout: 30000# 配置网络超时时间socketTimeout: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒timeBetweenEvictionRunsMillis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒minEvictableIdleTimeMillis: 300000# 配置一个连接在池中最大生存的时间,单位是毫秒maxEvictableIdleTimeMillis: 900000# 配置检测连接是否有效validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsewebStatFilter: enabled: truestatViewServlet:enabled: true# 设置白名单,不填则允许所有访问allow:url-pattern: /druid/*# 控制台管理用户名和密码login-username: Andy_Fan login-password: 123ss456filter:stat:enabled: true# 慢SQL记录log-slow-sql: trueslow-sql-millis: 1000merge-sql: truewall:config:multi-statement-allow: tr
2-DruidConfig 配置
/*** druid 配置多数据源** @author Andy_Fan** 在需要切换数据源的方法上加上@DataSource注解----加在serviceImpl方法上,或者mapper** @DataSource(value = DataSourceType.SLAVE)* @Select("select count(1) from public.\"LX_CJ_DK\"")*/
@Slf4j
@Configuration
public class DruidConfig
{/*** 主库数据源* @param druidProperties* @return*/@Bean@ConfigurationProperties("spring.datasource.druid.master")public DataSource masterDataSource( DruidProperties druidProperties ){log.info( "------主库数据源加载完成--masterDataSource-" );DruidDataSource dataSource = DruidDataSourceBuilder.create().build();return druidProperties.dataSource( dataSource );}/*** 从库数据源 1* @param druidProperties* @return*/@Bean@ConfigurationProperties("spring.datasource.druid.slave")@ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")public DataSource slaveDataSource( DruidProperties druidProperties ){log.info( "------从库数据源加载完成--slaveDataSource-" );DruidDataSource dataSource = DruidDataSourceBuilder.create().build();return druidProperties.dataSource( dataSource );}/*** 从库数据源 2 aaa* @param* @return*/@Bean@ConfigurationProperties("spring.datasource.druid.slave-aaa")@ConditionalOnProperty(prefix = "spring.datasource.druid.slave-aaa", name = "enabled", havingValue = "true")public DataSource slaveAAADataSource( DruidProperties druidProperties ){log.info( "------从库数据源加载完成--slaveAAADataSource-" );DruidDataSource dataSource = DruidDataSourceBuilder.create().build();return druidProperties.dataSource( dataSource );}@Bean(name = "dynamicDataSource")@Primarypublic DynamicDataSource dataSource( DataSource masterDataSource, DataSource slaveDataSource, DataSource slaveAAADataSource ){log.info( "------主从数据源加载完成---" );Map< Object, Object > targetDataSources = new HashMap<>();targetDataSources.put( DataSourceType.MASTER.name(), masterDataSource );targetDataSources.put( DataSourceType.SLAVE.name(), slaveDataSource );targetDataSources.put( DataSourceType.SLAVE_AAA.name(), slaveAAADataSource );// 在需要切换数据源的方法上加上@DataSource注解,@DataSource(value = DataSourceType.SLAVE)return new DynamicDataSource( masterDataSource, targetDataSources );}/*** 设置数据源** @param targetDataSources 备选数据源集合* @param sourceName 数据源名称* @param beanName bean名称*/public void setDataSource( Map< Object, Object > targetDataSources, String sourceName, String beanName ){try{log.info( "------加载数据源: targetDataSources{}", targetDataSources + "------: sourceName {}", sourceName + "------: beanName{}", beanName );DataSource dataSource = SpringUtils.getBean( beanName );targetDataSources.put( sourceName, dataSource );}catch ( Exception e ){log.error( "------加载数据源失败, {}", e.getMessage() );}}
}
3- DynamicDataSource
```
/*** 动态数据源** @author Andy_Fan* @date 2024/09/11*/
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource
{public DynamicDataSource( DataSource defaultTargetDataSource, Map< Object, Object > targetDataSources ){log.info( "-----------DynamicDataSource init" );super.setDefaultTargetDataSource( defaultTargetDataSource );super.setTargetDataSources( targetDataSources );super.afterPropertiesSet();}@Overrideprotected Object determineCurrentLookupKey(){log.info( "------DynamicDataSource determineCurrentLookupKey" );return DynamicDataSourceContextHolder.getDataSourceType();}
}
4-DynamicDataSourceContext
/*** 数据源切换处理* @author Andy_Fan* @date 2024/09/11*/
public class DynamicDataSourceContextHolder
{public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);/*** 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。*/private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();/*** 设置数据源的变量** 增加DataSourceType类里面的枚举类型public enum DataSourceType{MASTER,SLAVE,SLAVE_XZDB}**/public static void setDataSourceType(String dsType){log.info("----切换数据源:", dsType);CONTEXT_HOLDER.set(dsType);}/*** 获得数据源的变量*/public static String getDataSourceType(){log.info("-----获取数据源:{}", CONTEXT_HOLDER.get());return CONTEXT_HOLDER.get();}/*** 清空数据源变量*/public static void clearDataSourceType(){log.info("-----清除数据源");CONTEXT_HOLDER.remove();}}
5-测试
/*** <p>* 用户表 服务实现类* </p>** @author Andy_Fan* @since 2024-09-12 14:52:06*/
@Service
public class DemoUserServiceImpl extends ServiceImpl< DemoUserMapper, DemoUser > implements IDemoUserService
{@Resourceprivate DemoUserMapper demoUserMapper;@Override@DataSource(value = DataSourceType.SLAVE)public List< DemoUser > selectList(){return demoUserMapper.selectAll( new DemoUser() );}}
----切换到SLAVE数据源
-----获取数据源:SLAVE
----获取数据源:null
.r.f.d.DynamicDataSourceContextHolder - [setDataSourceType,28] - ----切换到SLAVE数据源
15:52:06.280 [http-nio-8080-exec-1] INFO c.r.f.d.DynamicDataSourceContextHolder - [getDataSourceType,38] - -----获取数据源:SLAVE
15:52:06.283 [http-nio-8080-exec-1] DEBUG c.r.d.m.D.selectAll - [debug,135] - ==> Preparing: select id, username, password, nickName, third_party_id, avatar, avatar_thumbnail, gender, user_type, last_login_time, registration_ip, deleted, version, create_date, create_by, update_date, update_by from demo_user
15:52:06.289 [http-nio-8080-exec-1] DEBUG c.r.d.m.D.selectAll - [debug,135] - ==> Parameters:
15:52:06.429 [http-nio-8080-exec-1] DEBUG c.r.d.m.D.selectAll - [debug,135] - <== Total: 2
15:52:06.430 [http-nio-8080-exec-1] INFO c.r.f.d.DynamicDataSourceContextHolder - [clearDataSourceType,47] - -----清除数据源
一起加油,一起向前冲。。。
相关文章:

springboot配置多数据源
springboot配置多数据源 学习新技术,争做新青年,欢迎围观,河南老乡在上海请,加,微,andyfau2022, ----获取数据源:null,数据源为null时默认使用主数据源的。 1-yml文件…...
无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案
墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切…...

ChatGPT+Simple Mind Map生成思维导图:快速提升学习效率
一、告别杂乱笔记,一键生成清晰思维导图! 最近开始学习网络安全,一头扎进了各种协议、漏洞、防御机制的海洋中。信息量巨大,知识点零散,让我很快便陷入了“知识焦虑”——笔记越记越多,却越来越混乱&#…...

Day9 | Java框架 | SpringBoot
Day9 | Java框架 | SpringBoot SpringBoot简介入门程序概述起步依赖 基础配置配置文件格式:3种yaml语法规则yaml数据读取三种格式 多环境启动配置文件参数命令行参数多环境开发控制:Maven & SpringBoot 多环境兼容 配置文件分类:4种 整合…...
Wordpress右下角表单弹出插件
Ultimate Sticky Popup & Widgets Charcoal Making Machine | Equipment for Sale - Kingtiger...

影刀RPA实战:自动化批量生成条形码完整指南
今天我们聊聊使用影刀来实现批量生成条形码,条形码在零售行业运用非常广泛,主要作用表现在产品识别,库存管理,销售管理,防伪保护等,这些作用使其成为现代商业和工业环境中不可或缺的工具,它极大…...
Python Flask简介
简介 Flask 有两个主要依赖:路由、调试和 Web 服务器网关接口(Web Server Gateway Interface,WSGI) 子系统由:Werkzeug 提供模板系统由:Jinja2提供Werkzeug 和 Jinjia2 都是由 Flask 的核心开发者开发而成…...

视频监控平台是如何运作的?EasyCVR视频汇聚平台的高效策略与实践
随着科技的飞速发展,视频监控平台在社会安全、企业管理、智慧城市构建等领域发挥着越来越重要的作用。一个高效的视频监控平台,不仅依赖于先进的硬件设备,更离不开强大的视频处理技术作为支撑。这些平台集成了多种先进的视频技术,…...

欧拉下搭建第三方软件仓库—docker
1.创建新的文件内容 切换目录到etc底下的yum.repos.d目录,创建docker-ce.repo文件 [rootlocalhost yum.repos.d]# cd /etc/yum.repos.d/ [rootlocalhost yum.repos.d]# vim docker-ce.repo 编辑文件,使用阿里源镜像源,镜像源在编辑中需要单独复制 h…...

pcs升压变流一体机
在当今全球积极推进能源转型的大背景下,新能源技术的发展日新月异。其中,PCS 升压变流一体机作为一种关键的能源转换设备,正发挥着越来越重要的作用。它一般可分为10KV与35KV等级的。 PCS 升压变流一体机,全称为 Power Conversion…...

上海泗博EtherNet/IP转PROFIBUS DP网关EPS-320IP成都地铁项目应用案例
背景: 地铁,作为城市的活力脉搏,不仅是衔接城市生活的关键纽带,更是现代城市交通体系中不可或缺的核心组成部分。因此,确保地铁的稳定运行对任何一座城市都至关重要。 上海泗博自动化,作为与成都地铁项目合…...

猫鼠游戏: KaijiK病毒入侵溯源分析
1. 事件背景 近期,网宿平台某客户在使用云主机工作的时候突然出现主机卡顿,连接不稳定,网络断开的情况,并且收到了网宿主机入侵检测产品的告警信息。由于客户没有专职的安全人员,由运维人员兼任安全运营工作ÿ…...

【Hot100算法刷题集】双指针-02-盛水最多的容器(含暴力枚举、双指针法及其合理性证明)
🏠关于专栏:专栏用于记录LeetCode中Hot100专题的所有题目 🎯每日努力一点点,技术变化看得见 题目转载 题目描述 🔒link->题目跳转链接 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的…...

Spring和Spring FrameWork有什么关系?两者是同一个东西吗?
Spring和Spring Framework之间的关系可以归结为以下几点: 广义与狭义的理解 广义上的Spring: 广义上的Spring泛指以Spring Framework为基础的整个Spring技术栈。Spring已经发展成为一个由多个不同子项目(模块)组成的成熟技术体系…...

windows10 python 解决鼠标右键菜单中没有Edit with IDLE(不使用注册表编辑器)
随便选择一个py文件,右击打开属性。 打开方式:点击更改。 最下面:点击更多应用,点击在这台电脑上查找应用 搜索找到你自己按照的python路径下 Python39\Lib\idlelib\idle.bat 文件 点击打开,结束。...
一些深度学习相关指令
// 服务器上查看所有的环境版本 conda env list// 删除某一个环境 conda remove -n 环境名 --all终端输入命令:nvidia-smi,可以看显卡的使用情况指定使用哪张显卡: os.environ["CUDA_VISIBLE_DEVICES"] 2查看服务器的cuda版本&am…...
Python 实现自动配置华为交换机
Python 实现自动配置华为交换机 在网络运维中,配置交换机是非常重要的一步。如果我们可以使用 Python 来实现配置交换机,那么我们的工作效率将会大大提高。在本文中,我们将学习如何使用 Python 配置华为交换机。 背景知识 华为交换机是一种…...

上海亚商投顾:沪指探底回升 华为产业链午后爆发
上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 沪指昨日探底回升,深成指、创业板指盘中跌逾1%,午后集体拉升翻红。华为产业链午后走强…...

回归预测 | MATLAB实现PSO-LSTM(粒子群优化长短期记忆神经网络)多输入单输出
回归预测 | MATLAB实现PSO-LSTM(粒子群优化长短期记忆神经网络)多输入单输出 目录 回归预测 | MATLAB实现PSO-LSTM(粒子群优化长短期记忆神经网络)多输入单输出预测效果基本介绍模型介绍PSO模型LSTM模型PSO-LSTM模型程序设计参考资料致谢预测效果 Matlab实现PSO-LSTM多变量回归…...
Linux seq命令
参考资料 知っておくとちょっと便利!seq コマンドの使い方をご紹介 目录 一. 基本语法二. 选项2.1 -f 格式化输出2.2 -s 指定分隔符2.3 -w 输出数字补齐宽度 三. 小案例3.1 递减序列3.2 批量创建测试文件3.3 批量下载文件 一. 基本语法 seq [OPTION] 结束值 seq […...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...