實例講解Spring boot動態切換數據源

来源:https://www.cnblogs.com/huaweiyun/archive/2023/05/26/17434200.html
-Advertisement-
Play Games

摘要:本文模擬一下在主庫查詢訂單信息查詢不到的時候,切換數據源去歷史庫裡面查詢。 本文分享自華為雲社區《springboot動態切換數據源》,作者:小陳沒煩惱 。 前言 在公司的系統里,由於數據量較大,所以配置了多個數據源,它會根據用戶所在的地區去查詢那一個資料庫,這樣就產生了動態切換數據源的場景。 ...


摘要:本文模擬一下在主庫查詢訂單信息查詢不到的時候,切換數據源去歷史庫裡面查詢。

本文分享自華為雲社區《springboot動態切換數據源》,作者:小陳沒煩惱 。

前言

在公司的系統里,由於數據量較大,所以配置了多個數據源,它會根據用戶所在的地區去查詢那一個資料庫,這樣就產生了動態切換數據源的場景。

今天,就模擬一下在主庫查詢訂單信息查詢不到的時候,切換數據源去歷史庫裡面查詢。

實現效果

首先我們設置查詢的資料庫為db1,可以看到通過訂單號沒有查到訂單信息,然後我們重置數據源,重新設置為db2,同樣的訂單號就可以查詢到信息。

資料庫準備

新建兩個資料庫db1和db2,db1作為主庫,db2作為歷史庫

兩個庫中都有一個訂單表biz_order,主庫中沒有數據,歷史庫中有我們要查詢的數據。

代碼編寫

1.新建一個springboot項目,引入所需依賴

 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter</artifactId>
 </dependency>
 <!--引入druid-替換預設資料庫連接池-->
 <dependency>
 <groupId>com.alibaba</groupId>
 <artifactId>druid-spring-boot-starter</artifactId>
 <version>1.2.15</version>
 </dependency>
 <dependency>
 <groupId>org.mybatis.spring.boot</groupId>
 <artifactId>mybatis-spring-boot-starter</artifactId>
 <version>2.2.2</version>
 </dependency>
 <!--mysql驅動-->
 <dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 <version>8.0.30</version>
 </dependency>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-test</artifactId>
 <scope>test</scope>
 </dependency>

2.application.yaml配置資料庫信息

這裡我們配置兩個資料庫的信息

spring:
 datasource:
    db1:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost/db1?characterEncoding=utf8&characterSetResults=utf8&autoReconnect=true&failOverReadOnly=false
      username: root
      password: root
      type: com.alibaba.druid.pool.DruidDataSource
    db2:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost/db2?characterEncoding=utf8&characterSetResults=utf8&autoReconnect=true&failOverReadOnly=false
      username: root
      password: root
      type: com.alibaba.druid.pool.DruidDataSource
mybatis:
  mapper-locations: classpath:mapper/*.xml

3.創建數據源對象,並註入spring容器中

新建DynamicDataSourceConfig.java文件,在該配置文件中讀取yaml配置的數據源信息,並且通過該信息構造數據源對象,然後通過@Bean註解註入到spring容器中。

package com.it1997.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.beans.factory.annotation.Qualifier;
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 DynamicDataSourceConfig {
    @Bean("dataSource1")
    @ConfigurationProperties(prefix = "spring.datasource.db1")
 public DataSource oneDruidDataSource() {
 return DruidDataSourceBuilder.create().build();
 }
    @Bean("dataSource2")
    @ConfigurationProperties(prefix = "spring.datasource.db2")
 public DataSource twoDruidDataSource() {
 return DruidDataSourceBuilder.create().build();
 }
    @Bean
 public DataSourceTransactionManager dataSourceTransactionManager1(@Qualifier("dataSource1") DataSource dataSource1) {
 DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
 dataSourceTransactionManager.setDataSource(dataSource1);
 return dataSourceTransactionManager;
 }
    @Bean
 public DataSourceTransactionManager dataSourceTransactionManager2(@Qualifier("dataSource2") DataSource dataSource2) {
 DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
 dataSourceTransactionManager.setDataSource(dataSource2);
 return dataSourceTransactionManager;
 }
}

4.數據源配置上下文信息

新建DynamicDataSourceHolder.java文件,該文件通過ThreadLocal,實現為每一個線程創建一個保存數據源配置的上下文。並且提供setDataSource和getDataSource靜態方法來設置和獲取數據源的名稱。

package com.it1997.config;
public class DynamicDataSourceHolder {
 private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
 public static void setDataSource(String dataSource) {
 contextHolder.set(dataSource);
 }
 public static String getDataSource() {
 return contextHolder.get();
 }
 public static void clearDataSource() {
 contextHolder.remove();
 }
}

5.重寫數據源配置類

新建DynamicDataSource.java文件,該類繼承AbstractRoutingDataSource 類,重寫父類determineCurrentLookupKey和afterPropertiesSet方法。

這裡我們重寫父類中afterPropertiesSet方法(為什麼要重寫在這個方法,可以看文章最後對於druid的源碼的講解),在這個方法里我們將spring容器中的所有的數據源,都給放到map里,然後後續我們根據map中的key來獲取不同的數據源,super.afterPropertiesSet();通過這個方法設置上數據源。

在類上加上@Primary註解,讓spring容器優先使用我們自定義的數據源,否則還是會使用預設的數據源配置。

package com.it1997.config;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Component
@Primary
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Resource
 DataSource dataSource1;
    @Resource
 DataSource dataSource2;
    @Override
 protected Object determineCurrentLookupKey() {
 return DynamicDataSourceHolder.getDataSource();
 }
    @Override
 public void afterPropertiesSet() {
 // 初始化所有數據源
        Map<Object, Object> targetDataSource = new HashMap<>();
 targetDataSource.put("db1", dataSource1);
 targetDataSource.put("db2", dataSource2);
 super.setTargetDataSources(targetDataSource);
 super.setDefaultTargetDataSource(dataSource1);
 super.afterPropertiesSet();
 }
}

druid數據源配置解讀

點開我們剛剛繼承的AbstractRoutingDataSource抽象類,可以看到它又繼承了AbstractDataSource 實現了InitializingBean介面。

然後我們在看一下druid的數據源配置是怎麼實現的,點開DruidDataSourceWrapper類,可以看到它也是繼承了AbstractDataSource 實現了InitializingBean介面。並且,讀取的是yaml文件中spring.datasource.druid下麵配置的資料庫連接信息。

而我們自定的一的數據源讀取的是spring.datasource.db1下麵配置的資料庫連接信息。

druid的數據源配置,實現了介面中afterPropertiesSet,在這個方法中設置了資料庫的基本信息,例如,資料庫連接地址、用戶名、密碼以及資料庫連接驅動信息。

 

點擊關註,第一時間瞭解華為雲新鮮技術~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ## Doris 簡介 ### Doris 概述 Apache Doris 由百度大數據部研發 (之前叫百度 Palo,2018 年貢獻到 Apache 社區後,更名為 Doris), 在百度內部,有超過 200 個產品線在使用,部署機器超過 1000 台,單一業務最大可達到上百 TB。 Apach ...
  • 我們介紹一下SeaTunnel支持的第一個同步場景:離線批量同步。顧名思意,離線批量同步需要用戶定義好SeaTunnel JobConfig,選擇批處理模式,作業啟動後開始同步數據,當數據同步完成後作業完成退出。 ...
  • 雖然感覺生活小知識沒有多少人喜歡看,這主要是因為生活小知識的策略不對,比如你要讓別人一時間接受20條還不如一天推一條,讓別人20天記住20條來得好,也不會讓訪客感到厭煩。 一級分類包含:安全急救(1445)、奧運知識(206)、服飾裝扮(512)、家電電腦(555)、健康養生(4390)、經營理財( ...
  • 摘要:此篇文章分別從sql執行過程、執行計劃、索引數據結構、索引查詢提速原理、聚焦索引、左首碼優化原則、自增主鍵索引這些角度談一談我們對資料庫優化的理解。 本文分享自華為雲社區《工程應用中資料庫性能優化經驗小結》,作者: 葉工 。 1、前言 現階段交付的演算法產品,絕大多數涉及到資料庫的使用。它承載的 ...
  • 中醫古文字經過千年的演變,字的本義與現在的含義已相去甚遠,中醫專業的學生或中醫愛好者研習傳統醫學經典,必需有一個方便易用的字典工具,《近萬條中醫名詞術語大全ACCESS資料庫》就能幫你實現。欄位信息、每個欄位的內容信息、記錄數信息等都請觀看截圖。 本資料庫是由 Microsoft Access 20 ...
  • 摘要:本文將聚焦於用戶監控的原理及應用進行介紹。 本文分享自華為雲社區《GaussDB(DWS)監控工具指南(二)用戶級監控》,作者:幕後小黑爪 。 前言 資源監控是整個運維乃至整個產品生命周期重要的一環,事前及時語句發現故障,事後提供詳實的數據用於追查定位問題。GaussDB(DWS)整個資源監控 ...
  • 近萬條一級分類經典簡訊大全ACCESS資料庫收集的是近萬條常用經典簡訊,之所以稱“一級分類”(意思是只有一個大類沒有子類),原因是為了區別另外一個有二級分類的簡訊資料庫。近萬條一級分類經典簡訊大全ACCESS資料庫中的簡訊都是經過索引沒有收錄重覆的記錄。 大類分類情況是:愛情簡訊(1730)、搞笑短 ...
  • 《5284個中醫葯基本名詞中醫名詞ACCESS資料庫》共收集中醫葯基本名詞5284個,分類情況統計:01.總論(45)、02.醫史文獻(275)、03.中醫基礎理論(804)、04.診斷學(930)、05.治療學(399)、06.中藥學(640)、07.方劑學(560)、08.針灸學(708)、09 ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...