實例講解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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...