2025-spring boot 之多數據源管理

1、是使用Spring提供的AbstractRoutingDataSource抽象類
注入多個數據源。
?

創建?DataSourceConfig 配置類? 通過spring jdbc 提供的帶路由的抽象數據源?AbstractRoutingDataSource


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   // 將該Bean設置為主要注入Bean
public class DynamicDataSource extends AbstractRoutingDataSource {// 當前使用的數據源標識public static ThreadLocal<String> name = new ThreadLocal<>();// 寫@AutowiredDataSource dataSource1;// 讀@AutowiredDataSource dataSource2;// 返回當前數據源標識@Overrideprotected Object determineCurrentLookupKey() {return name.get();}@Overridepublic void afterPropertiesSet() {// 為targetDataSources初始化所有數據源Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("W", dataSource1);targetDataSources.put("R", dataSource2);super.setTargetDataSources(targetDataSources);// 為defaultTargetDataSource 設置默認的數據源super.setDefaultTargetDataSource(dataSource1);super.afterPropertiesSet();}
}

讀取配置文件數據源

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.tuling.dynamic.datasource.DynamicDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource;@Configuration
public class DataSourceConfig {@Bean@ConfigurationProperties(prefix = "spring.datasource.datasource1")public DataSource dataSource1() {// 底層會自動拿到spring.datasource中的配置, 創建一個DruidDataSourcereturn DruidDataSourceBuilder.create().build();}@Bean@ConfigurationProperties(prefix = "spring.datasource.datasource2")public DataSource dataSource2() {// 底層會自動拿到spring.datasource中的配置, 創建一個DruidDataSourcereturn DruidDataSourceBuilder.create().build();}@Beanpublic DataSourceTransactionManager transactionManager1(DynamicDataSource dataSource) {DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();dataSourceTransactionManager.setDataSource(dataSource);return dataSourceTransactionManager;}@Beanpublic DataSourceTransactionManager transactionManager2(DynamicDataSource dataSource) {DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();dataSourceTransactionManager.setDataSource(dataSource);return dataSourceTransactionManager;}
}

配置文件

spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedatasource1:url: jdbc:mysql://127.0.0.1:3306/datasource1?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=falseusername: rootpassword: 123456initial-size: 1min-idle: 1max-active: 20test-on-borrow: truedriver-class-name: com.mysql.cj.jdbc.Driverdatasource2:url: jdbc:mysql://127.0.0.1:3306/datasource2?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=falseusername: rootpassword: 123456initial-size: 1min-idle: 1max-active: 20test-on-borrow: truedriver-class-name: com.mysql.cj.jdbc.Driver

自定義數據源注解


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.METHOD, ElementType.TYPE})
// 保留方式
@Retention(RetentionPolicy.RUNTIME)
public @interface WR {String value() default "W";
}

注解的實現方法

import com.tuling.dynamic.datasource.DynamicDataSource;
import com.tuling.dynamic.datasource.annotation.WR;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;@Component
@Aspect
public class DynamicDataSourceAspect implements Ordered {// 前置@Before("within(com.tuling.dynamic.datasource.service.impl.*) && @annotation(wr)")public void before(JoinPoint point, WR wr) {String name = wr.value();DynamicDataSource.name.set(name);System.out.println(name);}@Overridepublic int getOrder() {return 0;}// 環繞通知
}

2、使用dynamic-datasource框架

dynamic-datasource是MyBaits-plus作者設計的一個多數據源開源方案。使用這個框架需要引入對應的pom依賴

引入依賴

<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.0</version>
</dependency>

添加配置文件?

spring:datasource:dynamic:#設置默認的數據源或者數據源組,默認值即為masterprimary: master#嚴格匹配數據源,默認false. true未匹配到指定數據源時拋異常,false使用默認數據源strict: falsedatasource:master:url: jdbc:mysql://127.0.0.1:3306/datasource1?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=falseusername: rootpassword: 123456initial-size: 1min-idle: 1max-active: 20test-on-borrow: truedriver-class-name: com.mysql.cj.jdbc.Driverslave_1:url: jdbc:mysql://127.0.0.1:3306/datasource2?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=falseusername: rootpassword: 123456initial-size: 1min-idle: 1max-active: 20test-on-borrow: truedriver-class-name: com.mysql.cj.jdbc.Driver

?無需任何配置文件? 需要在services 指定數據源 ? 使用@DS注解

通過注解 查看源碼 點進入 注解

通過點進入 注解? 找到對應的源碼包

找到spring.factories 配置文件 找到核心自動配置類

找到數據源??DynamicRoutingDataSource?

mp 苞米豆 對 spring jdbc 封裝的,

通過實現接口?InitializingBean

源碼分析

通過?dynamicTransactionAdvisor方法 進行攔截 實現事務

DynamicLocalTransactionInterceptor 本地事務

?執行事務的? invoke 方法?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896257.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896257.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896257.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

keycloak - 開發環境的配置持久化

keycloak - 開發環境的配置持久化 前情提要&#xff1a; Keycloak - docker 運行 & 前端集成 本來是想順便試一下 Okta 集成的&#xff0c;但是發現 Okta 沒有本地的 docker 鏡像&#xff0c;他們畢竟是做 Identity as a service……算了…… 更新后的 docker compose 如…

項目實戰--網頁五子棋(匹配模塊)(4)

上期我們完成了游戲大廳的前端部分內容&#xff0c;今天我們實現后端部分內容 1. 維護在線用戶 在用戶登錄成功后&#xff0c;我們可以維護好用戶的websocket會話&#xff0c;把用戶表示為在線狀態&#xff0c;方便獲取到用戶的websocket會話 package org.ting.j20250110_g…

第4章 4.4 EF Core數據庫遷移 Add-Migration UpDate-Database

4.4.1 數據庫遷移原理 總結一下就是&#xff1a; 1. 數據庫遷移命令的執行&#xff0c;其實就是生成在數據庫執行的腳本代碼&#xff08;兩個文件&#xff1a;數字_遷移名.cs 數字_遷移名.Designer.cs&#xff09;&#xff0c;用于對數據庫進行定義和修飾。 2. 數據庫遷移…

Spring Boot + JSqlParser:全面解析數據隔離最佳實踐

Spring Boot JSqlParser&#xff1a;全面解析數據隔離最佳實踐 在構建多租戶系統或需要進行數據權限控制的應用時&#xff0c;數據隔離是一個至關重要的課題。不同租戶之間的數據隔離不僅能夠確保數據的安全性&#xff0c;還能提高系統的靈活性和可維護性。隨著業務的擴展和需…

51單片機編程學習筆記——點亮LED

大綱 器件51單片機開發板總結 安裝驅動點亮LED燒錄 隨著最近機器人爆火&#xff0c;之前寫的ROS2系列博客《Robot Operating System》也獲得了更多的關注。我決定在機器人領域里再走一步&#xff0c;于是想到可以學習單片機。研究了下學習路徑&#xff0c;最后還是選擇先從51單…

Java String 類

Java String 類常用方法詳解 在 Java 編程里&#xff0c;字符串操作十分常見&#xff0c;而 String 類作為 Java 標準庫的核心類&#xff0c;用于表示不可變的字符序列。任何對字符串的修改操作都會返回一個新的字符串對象&#xff0c;不會改變原始字符串。本文將詳細介紹 Str…

9.【線性代數】—— 線性相關性, 向量空間的基,維數

九 線性相關性&#xff0c; 向量空間的基&#xff0c;維數 Ax0 什么情況下無解(x不為零向量)1. 向量組的線性無關性2.向量組生成一個空間(S)3. 向量空間的一組基&#xff1a;都滿足向量個數相同4. 空間維數 基向量的個數 Ax0 什么情況下無解(x不為零向量) Ax0無解&#xff0c…

藍橋杯單片機組第十二屆省賽第二批次

前言 第十二屆省賽涉及知識點&#xff1a;NE555頻率數據讀取&#xff0c;NE555頻率轉換周期&#xff0c;PCF8591同時測量光敏電阻和電位器的電壓、按鍵長短按判斷。 本試題涉及模塊較少&#xff0c;題目不難&#xff0c;基本上準備充分的都能完整的實現每一個功能&#xff0c;并…

opencv:距離變換 cv2.distanceTransform

函數 cv2.distanceTransform() 用于計算圖像中每一個非零點像素與其最近的零點像素之間的距離&#xff08;Distance Transform&#xff0c; DT算法&#xff09;,輸出的是保存每一個非零點與最近零點的距離信息&#xff1b;圖像上越亮的點&#xff0c;代表了離零點的距離越遠。 …

基于Spring Boot的黨員學習交流平臺設計與實現(LW+源碼+講解)

專注于大學生項目實戰開發,講解,畢業答疑輔導&#xff0c;歡迎高校老師/同行前輩交流合作?。 技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;…

自動駕駛兩個傳感器之間的坐標系轉換

有兩種方式可以實現兩個坐標系的轉換。 車身坐標系下一個點p_car&#xff0c;需要轉換到相機坐標系下&#xff0c;旋轉矩陣R_car2Cam&#xff0c;平移矩陣T_car2Cam。點p_car在相機坐標系下記p_cam. 方法1&#xff1a;先旋轉再平移 p_cam T_car2Cam * p_car T_car2Cam 需要注…

k8s ssl 漏洞修復

針對Kubernetes集群中SSL/TLS協議信息泄露漏洞&#xff08;CVE-2016-2183&#xff09;的修復&#xff0c;需重點修改涉及弱加密算法的組件配置。以下是具體修復步驟及驗證方法&#xff1a; 一、漏洞修復步驟 1. 修復etcd服務 修改配置文件 &#xff1a; 編輯 /etc/kubernetes/…

數字IC后端培訓教程| 芯片后端實戰項目中base layer drc violation解析

今天分享一個咱們社區IC后端訓練營學員遇到的一個經典DRC案例。這個DRC Violation的名字為PP.S.9(這里的PP就是Plus P)。這一層是屬于管子的base layer。更多關于base layer的介紹&#xff0c;可以查看下面這份教程。 https://alidocs.dingtalk.com/api/doc/transit?spaceId5…

從零到一學習c++(基礎篇--筑基期十一-類)

從零到一學習C&#xff08;基礎篇&#xff09; 作者&#xff1a;羨魚肘子 溫馨提示1&#xff1a;本篇是記錄我的學習經歷&#xff0c;會有不少片面的認知&#xff0c;萬分期待您的指正。 溫馨提示2&#xff1a;本篇會盡量用更加通俗的語言介紹c的基礎&#xff0c;用通俗的語言去…

DeepSeek技術全景解析:架構創新與行業差異化競爭力

一、DeepSeek技術體系的核心突破 架構設計&#xff1a;效率與性能的雙重革新 Multi-head Latent Attention (MLA)&#xff1a;通過將注意力頭維度與隱藏層解耦&#xff0c;實現顯存占用降低30%的同時支持4096超長上下文窗口。深度優化的MoE架構&#xff1a;結合256個路由專家…

插入排序:一種簡單而直觀的排序算法

大家好&#xff01;今天我們來聊聊一個簡單卻非常經典的排序算法——插入排序&#xff08;Insertion Sort&#xff09;。在所有的排序算法中&#xff0c;插入排序是最直觀的一個。 一、插入排序的基本思想 插入排序的核心思想是&#xff1a;將一個待排序的元素&#xff0c;插…

2025年校園網絡招聘會匯總

1、衛生健康行業2025屆畢業生春季校園網絡招聘會 企業數量職位數量崗位數量10020002000 訪問地址&#xff1a; https://www.weirenjob.com/zph/zph_wsjkxy2025jbyscjxywlzph/ 2、山東地區面向2025屆高校畢業生網絡招聘活動 企業數量職位數量崗位數量909271052434 訪問地址&a…

Windows 10 GPU STACK 0.5.1 安裝

Windows 10 GPU STACK 0.5.1 安裝 1 GPUStack 安裝1.Python安裝&#xff08;3.10/11/12&#xff09;2.GPUStack 下載3.生成密碼4.訪問5.設置模型下載目錄6.禁用開機自啟并重啟服務7.安裝模型8.查看安裝的進度 2.試驗場聊天測試1.對話模式 3.API Key 測試 1 GPUStack 安裝 1.Py…

【數據結構】快指針和慢指針

一、 給你單鏈表的頭結點 head ,請你找出并返回鏈表的中間結點。如果有兩個中間結點,則返回第二個中間結點。 要求&#xff1a;只遍歷一遍鏈表 可以使用快慢指針&#xff1a;fast 一次走兩步&#xff0c;slow 一次走一步。當 fast NULL&#xff08;偶數個結點&#xff09;或…

1.3 嵌入式系統的固件

嵌入式系統的固件&#xff0c;一般情況下的作用是: 1.硬件抽象層&#xff08;HAL&#xff09;&#xff1a;固件提供了一個硬件抽象層&#xff0c;它將硬件的復雜性隱藏起來&#xff0c;為上層軟件提供了一套標準的接口。這樣&#xff0c;操作系統和應用程序不需要直接與硬件打交…