当前位置: 首页 > news >正文

AbstractRoutingDataSource,spring配置多数据源问题

AbstractRoutingDataSource,spring配置多数据源问题

首先引入pom.xml依赖

        <!--测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.3.12.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.3.12.RELEASE</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.0.1</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.1.1</version></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.2.13</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.18</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.1.1</version></dependency>

在application.yml中添加配置

spring:application:name: tmsdatasource:type: com.alibaba.druid.pool.DruidDataSourceds1:driver-class-name: Driverurl: ${url}username: ${username}password: ${password}ds2:driver-class-name: Driverurl: ${url}username: ${username}password: ${password}

其中加了两个数据库配置

添加这两个数据库的配置, 注入到bean

package com.dualdb;import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;@Configuration
public class MyBootDataSourceConfig {@Bean@ConfigurationProperties(prefix = "spring.datasource.ds1")public DataSource dataSource1() {// 通过配置地址拿到spring.datasource中的配置,创建一个DruidDataSourcereturn DruidDataSourceBuilder.create().build();}@Bean@ConfigurationProperties(prefix = "spring.datasource.ds2")public DataSource dataSource2() {// 通过配置地址拿到spring.datasource中的配置,创建一个DruidDataSourcereturn DruidDataSourceBuilder.create().build();}
}

配置这两个数据源的主从关系, 及切换标识

package com.config.dualdb;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;@Component
@Primary // 有多个datasource时,将此source设置为主要注入的bean,primary
public class DynamicDatasource extends AbstractRoutingDataSource {// 数据源标识,为了保证线程安全使用threadLocalpublic static ThreadLocal<String> threadLocal = new ThreadLocal<>();@AutowiredDataSource dataSource1;@AutowiredDataSource dataSource2;/*** 此方法作用是返回当前数据源标识** @return*/@Overrideprotected Object determineCurrentLookupKey() {return threadLocal.get();}/*** 重写父类方法之前,为父类基础属性进行赋值*/@Overridepublic void afterPropertiesSet() {// 为AbstractRoutingDataSource的主要参数进行赋值// targetDataSources初始化所有数据源Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("ds1", dataSource1);targetDataSources.put("ds2", dataSource2);super.setTargetDataSources(targetDataSources);// defaultTargetDataSource设置默认数据源super.setDefaultTargetDataSource(dataSource1);super.afterPropertiesSet();}// 清除threadLocal变量
}

使用aop方式自动切换数据源

package com.aop;import com.config.dualdb.DynamicDatasource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;@Component
@Aspect
@Slf4j
public class DynamicDatasourceAspect {@Pointcut("execution(public * com.mapper.test1.*.*(..))")public void pointCut1() {}@Pointcut("execution(public * com.mapper.test2.*.*(..))")public void pointCut2() {}@Before(value = "pointCut1()")public void before1(JoinPoint jp) {String name = "解析token获取用户对应的数据源";// 通过反射拿到请求的相关信息,进行解析,获取相应的标识// 根据具体业务对应的标识设置请求哪个数据源// 优化点, 根据切点, 动态切换配置DynamicDatasource.threadLocal.set("ds1");log.info(name);}@After("pointCut1()")public void after1(JoinPoint joinPoint) {DynamicDatasource.threadLocal.remove();}@Before(value = "pointCut2()")public void before2(JoinPoint jp) {String name = "解析token获取用户对应的数据源";// 通过反射拿到请求的相关信息,进行解析,获取相应的标识// 根据具体业务对应的标识设置请求哪个数据源DynamicDatasource.threadLocal.set("ds2");log.info(name);}@After("pointCut2()")public void after2(JoinPoint joinPoint) {DynamicDatasource.threadLocal.remove();}
}

简单编写aop自动切换,通过解析当前执行包名称,自动获取数据源标识符,然后设置当前数据源,注意需要修改mapper目录下的包为对应数据源名称

import com.config.dualdb.DynamicDatasource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;@Component
@Aspect
@Slf4j
public class DynamicDatasourceAspect {@Pointcut("execution(public * com.mapper.*.*.*(..))")public void pointCut1() {}@Before(value = "pointCut1()")public void before1(JoinPoint jp) {String name = "解析token获取用户对应的数据源";// 通过反射拿到请求的相关信息,进行解析,获取相应的标识// 根据具体业务对应的标识设置请求哪个数据源final String[] split = jp.getSignature().getDeclaringTypeName().split("\\.");String flag = split[split.length - 2];DynamicDatasource.threadLocal.set(flag);log.info(name);}@After("pointCut1()")public void after1(JoinPoint joinPoint) {DynamicDatasource.threadLocal.remove();}
}

参考:
配置参考:
【spring配置多数据源】spring连接多个数据库,同一套项目配置多个数据库
声明事务参考:
mybatis(plus)多数据源

相关文章:

AbstractRoutingDataSource,spring配置多数据源问题

AbstractRoutingDataSource&#xff0c;spring配置多数据源问题 首先引入pom.xml依赖 <!--测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.3.12.RE…...

日常BUG—— SpringBoot项目DEBUG模式启动慢、卡死。

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;日常BUG、BUG、问题分析☀️每日 一言 &#xff1a;存在错误说明你在进步&#xff01; 一、问题描述 我们调试程序时&#xff0c;需要使用DEBUG模式启动SpringBoot项目&#xff0c; 有时候会发…...

Linux网络编程(TCP状态转换关系)

文章目录 前言一、TCP状态转换图二、TCP连接状态转换解析三、TCP断开状态转换解析四、为什么需要有2MLS时长总结 前言 本篇文章来讲解一下TCP的状态转换关系&#xff0c;学习这个状态转换关系对于我们深入了解网络编程是非常有必要的。 一、TCP状态转换图 二、TCP连接状态转换…...

tauri-vue:快速开发跨平台软件的架子,支持自定义头部UI拖拽移动和窗口阴影效果

Tauri Vue Typescript 一个使用 taurivuets 开发跨平台软件的模板&#xff0c;支持窗口头部自定义 UI 和拖拽和窗口阴影&#xff0c;不用再自己做适配了&#xff0c;拿来即用&#xff0c;非常 nice。而且已经封装好了 tauri 的 http 请求工具&#xff0c;省去很多弯路。开源…...

做好以下几点,可以让我们延长周末体验感,好好放松!!!

工作以后常常容易感到疲于奔命&#xff0c;让我们找到适合自己方式&#xff0c;来让我们度过一个充实放松的周末! 方向一&#xff1a;分享你周末的时间规划 我们可以把每个月当做一个周期&#xff0c;制定一个简单的计划&#xff0c;如&#xff1a;第一周&#xff0c;锻炼身体…...

Python 学习笔记——代码基础

目录 Python基础知识 变量 赋值 数据类型 print用法 print格式化输出 运算符 if-else 数据结构 元组 in运算符 列表 切片 [ : ] 追加 append() 插入 insert&#xff08;&#xff09; 删除 pop() 字典 循环 for循环 for循环应用——遍历 for循环应用——累加…...

Android Studio 无法正常导入项目

Android Studio 无法正常导入 model&#xff0c;运行按钮边出现“Add Configuration”&#xff0c;可进行以下方法处理&#xff1a; 解决办法&#xff1a; 1、点击Run三角按钮左边紧挨的下拉按钮&#xff0c;选择Edit Configuration&#xff0c;选择 Default 新建一个Android…...

Grafana+Prometheus技术文档-进阶使用-监控spring-boot项目

阿丹&#xff1a; 之前已经实现了使用Prometheus来对服务器进行了监控和仪表盘的创建&#xff0c;现在就需要对这些监控方法使用在spring-boot中去。 实现思路&#xff1a; 1、集成Actuator 2、加入Prometheus的依赖 3、配置开放端口、以及开放监控 4、配置Prometheus中的配置…...

PG常用SQL

数据库 创建数据库 PostgreSQL 创建数据库可以用以下三种方式&#xff1a; 1、使用 CREATE DATABASE SQL 语句来创建。2、使用 createdb 命令来创建。3、使用 pgAdmin 工具。 CREATE DATABASE 创建数据库 CREATE DATABASE 命令需要在 PostgreSQL 命令窗口来执行&#xff0…...

分模块开发的意义及开发步骤

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaweb 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 Maven进阶 一、分模块开发1.1分模块开发的意义1.2分模块开…...

vue-router中的一些 API

在Vue.js的vue-router中&#xff0c;一些重要api 1、RouterHistory&#xff1a;这是 vue-router 提供的路由历史记录对象。它可以跟踪当前页面的路由历史&#xff0c;并提供一些方法和属性来管理导航和历史记录。在 vue-router 中&#xff0c;有两种类型的路由历史记录对象&…...

go-zero 是如何实现令牌桶限流的?

原文链接&#xff1a; 上一篇文章介绍了 如何实现计数器限流&#xff1f;主要有两种实现方式&#xff0c;分别是固定窗口和滑动窗口&#xff0c;并且分析了 go-zero 采用固定窗口方式实现的源码。 但是采用固定窗口实现的限流器会有两个问题&#xff1a; 会出现请求量超出限…...

Oracle/PL/SQL奇技淫巧之ROWNUM伪列

ROWNUM伪列 ROWNUM是一个伪列&#xff0c;它是根据每次查询的结果动态生成的一列递增编号&#xff0c;表示 Oracle 从表中选择该行的顺序&#xff0c;选择的第一行ROWNUM为1&#xff0c;第二行ROWNUM为2&#xff0c;以此类推。 注意1&#xff1a; ROWNUM伪列是在WHERE子句之…...

“MongoDB基础知识【超详细】

"探索MongoDB的无边之境&#xff1a;沉浸式数据库之旅" 欢迎来到MongoDB的精彩世界&#xff01;在这个博客中&#xff0c;我们将带您进入一个充满创新和无限潜力的数据库领域。无论您是开发者、数据工程师还是技术爱好者&#xff0c;MongoDB都将为您带来一场令人心动…...

腾讯24届校招内推

校招开始啦&#xff5e;有兴趣的话可以扫我的码投&#xff0c;也可以分享给身边找工作的同学&#xff5e; ❤投递攻略 1️⃣腾讯校招步骤&#xff0c;先微信扫码绑定内推关系&#xff0c;后在电脑上上传更改简历和部门投递 2️⃣投递时将选择投递部门&#xff0c;投递后将在…...

星际争霸之小霸王之小蜜蜂(二)--类的使用

目录 前言 一、将设置内容写在一个类里 二、设置小蜜蜂的造型 三、设置猫蜜蜂的参数 四、绘制猫蜜蜂到窗口 总结 前言 昨天我们设置好了窗口&#xff0c;下面我们需要向窗口中添加元素了。 一、将设置内容写在一个类里 我个人理解书上的意思是要创建一个类&#xff0c;将所有需…...

AndroidStudio升级Gradle之坑

最近在做旧工程的升级&#xff0c;原来的Gradle版本是4.6的&#xff0c;需要升级到7.6&#xff0c;JDK从8升级到17&#xff0c;一路淌了很多坑&#xff0c;逐个记录下吧 1、Maven仓库需要升级到https 你会遇到这个报错 Using insecure protocols with repositories, without …...

C# int ? 关键字使用方法

使用C#的时间也不算短。 但是今天看到了一个从来没有见过的写法 Int &#xff1f;这是个什么写法&#xff0c;没见过啊&#xff0c;百度了查一下&#xff0c;也在这里记录一下。 1、int? 关键字说明 (1)、int? 表示一个int类型,且该int类型可空,如果不加?的话,那么int类…...

Redis_主从复制

8. 主从复制 8.1 简介 主从库采用读写分离的方式 读操作&#xff1a;主库、从库都可以处理写操作&#xff1a;首先写到主库执行&#xff0c;然后再将主库同步给从库。 实现读写分离&#xff0c;性能扩展 容灾快速恢复 8.2 主从复制步骤 创建一个目录 ,在root下创建一个m…...

Postman 的 Pre-request Script 使用RSA加解密

文章目录 一、概述 一、概述 Postman内置的Js不支持进行RSA加解密&#xff0c;所以需要引入forgeJS来实现。在 Pre-request Script使用以下脚本&#xff1a; // ------ 导入RSA ------ if (!pm.globals.has("forgeJS")) {pm.sendRequest("https://raw.githubu…...

HFSS仿真结果怎么看?以T型波导为例,读懂S参数与电场动态图

HFSS仿真结果深度解析&#xff1a;从S参数到电场动态图的实战指南当你第一次在HFSS中完成T型波导仿真后&#xff0c;面对满屏的曲线和彩色云图&#xff0c;是否感到既兴奋又困惑&#xff1f;那些起伏的S参数曲线究竟告诉你什么信息&#xff1f;电场图中跳跃的颜色又代表怎样的物…...

从Office功能区的“局外人“到“掌控者“:Office RibbonX Editor深度指南

从Office功能区的"局外人"到"掌控者"&#xff1a;Office RibbonX Editor深度指南 【免费下载链接】office-ribbonx-editor An overhauled fork of the original Custom UI Editor for Microsoft Office, built with WPF 项目地址: https://gitcode.com/g…...

Vue3 图片标框功能实现方案

基于 Vue3 组合式 API 的图片标框&#xff08;画框、标注、选框&#xff09;完整实现&#xff0c;核心逻辑封装在 GetBoxes 组件里&#xff0c;复制就能用 一、功能说明 ✅ 在图片上鼠标拖拽画矩形框 ✅ 实时显示框坐标&#xff08;x, y, width, height&#xff09; ✅ 支持多…...

为什么视频代剪辑会影响你的内容传播效果

为什么你精心拍的视频&#xff0c;发出去却没人看&#xff1f; 你有没有过这样的经历&#xff1a;花了一整天拍Vlog&#xff0c;素材画质高清、内容真实&#xff0c;可一剪出来就显得平淡无奇&#xff0c;点赞寥寥&#xff1f;或者婚礼当天感动全场&#xff0c;回看成片却像流水…...

飞书远程控机:OpenClaw配置全攻略

本文详细介绍如何通过 OpenClaw 工具对接飞书开放平台&#xff0c;配置智能机器人实现 Windows 电脑的远程控制。主要内容涵盖文件管理和程序启动等核心功能的实现方法&#xff0c;并提供完整的配置指南与常见问题解决方案。 一、使用前提说明 1. 系统要求 仅适用于 Windows…...

终极鼠标连点器使用指南:3分钟掌握高效自动化技巧

终极鼠标连点器使用指南&#xff1a;3分钟掌握高效自动化技巧 【免费下载链接】MouseClick &#x1f5b1;️ MouseClick &#x1f5b1;️ 是一款功能强大的鼠标连点器和管理工具&#xff0c;采用 QT Widget 开发 &#xff0c;具备跨平台兼容性 。软件界面美观 &#xff0c;操作…...

写论文的神助攻!好用的AI写作辅助软件,逻辑清晰质量高

作为一名刚完成毕业论文的过来人&#xff0c;我太懂写论文的痛苦了 —— 选题迷茫、文献浩如烟海、框架混乱、逻辑不清、反复修改、查重降重反复折腾... 直到我发现了这套 AI 写作工具组合&#xff0c;简直是论文写作的 "开挂神器"&#xff0c;效率直接拉满&#xff…...

翻译 GDB 官方文档

翻译 GDB 官方文档项目地址官方文档地址下载源码包编译html运行翻译程序项目地址 https://github.com/shootercheng/gdb-translate.git 项目结构 $ tree -L 1 . ├── cmd ├── go.mod ├── input ├── internal ├── LICENSE ├── output ├── README.md ├─…...

Windows Cleaner深度解析:5大核心模块彻底解决系统空间不足问题

Windows Cleaner深度解析&#xff1a;5大核心模块彻底解决系统空间不足问题 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服&#xff01; 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner Windows Cleaner是一款完全免费开源的…...

基于雷达与光敏传感器的低功耗智能窗防设备设计与实现

1. 项目概述&#xff1a;一个基于雷达与光敏的智能窗防设备几年前&#xff0c;我因为一次短暂的出差&#xff0c;家里空置了几天&#xff0c;回来后就一直琢磨着怎么给家里的窗户加点“动静”。市面上的智能安防摄像头固然好&#xff0c;但要么需要复杂的布线&#xff0c;要么云…...