日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

多库操作:多个数据库的动态切换(一)

發布時間:2023/12/4 数据库 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多库操作:多个数据库的动态切换(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

更多精彩推薦,上午11點到達

在平時的開發中,受到傳統模式的影響,我們都是習慣了單一的數據庫表操作,把數據都建到一個庫里邊,然后進行增刪改查,這個是很經典的開發模式。

但是隨著項目開發,總會出現這樣的應用場景:
1、我們新的系統建立了新庫,但是老板讓我們把具有相同結構的老數據庫也帶上(導入到一起或者定時同步,這里不討論)

2、項目慢慢變大,我們要分庫分表了,可能訂單數據和用戶數據被分開了,但是同一個api業務邏輯里,可能我們需要操作多個DB,比如我正在走的是主庫,然后有一個操作,需要把數據從另一個DB里區保存或者查詢。

3、想在測試的時候,同時無縫測試多個庫連接,比如我的Blog.Core,每次我提交一個版本,都需要對Sqlite、MySql、MSSql(LocalDB)等同時做測試,那我就想在不停掉項目的前提下,做多庫測試。

其實說了那么多,就是想實現一個工作,就是多庫操作,畢竟這是一個趨勢,今天我們就簡單說一下多庫操作的第一彈 —— 動態切換數據庫。過程很簡單,這里就先說一下吧。

鳴謝:@Game結束 小伙伴提供思路和代碼。

1、修改配置DB連接字符串集合

目前我的Blog.Core項目中,使用的是SqlSugar的ORM,如果你用其他的,也是可以的,思路都是一樣的,可能具體操作細節和寫法上不太一樣。

修改我們的appsettings.json,配置連接字符串

"DBS": [/*MySql = 0,SqlServer = 1,Sqlite = 2,Oracle = 3,PostgreSQL = 4*/{"ConnId": 1,// 連接id,可以配置到數據庫"DBType":?2,//?db類型,枚舉,具體的看上邊"Enabled": true,// 是否開啟當前數據庫db"Connection": "WMBlog.db" // 連接字符串},{"ConnId": 2,"DBType": 1,"Enabled": true,"Connection": "Server=.;Database=WMBlogDB;User ID=sa;Password=123;","ProviderName": "System.Data.SqlClient"},{"ConnId": 3,"DBType": 0,"Enabled": false,"Connection": "Server=localhost; Port=3306;Stmt=; Database=wmblogdb; Uid=root; Pwd=456;"},{"ConnId": 4,"DBType": 3,"Enabled": false,"Connection": "Provider=OraOLEDB.Oracle; Data Source=WMBlogDB; User Id=sss; Password=789;","OracleConnection_other1": "User ID=sss;Password=789;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.8.65)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME = orcl)))"}],

這個設計很簡單,我們可以配置到appsettings.json里,同時也可以配置到內存里,至于能不能放到數據庫里,我還沒有操作過,不過放到配置文件里已經基本可以了。

2、配置連接數據對象

我們這里使用的既然是Sqlsugar,那就把相應的連接配置對象注入到服務里,本來使用的是上下文,但是后來為了事務,也發現上下文有點兒多余,因為sqlsugar自帶了部分上下文的功能,所以就直接使用的ISqlSugarClient。

那首先我們就需要把剛剛json配置文件的連接字符串,封裝一下:

在 Common 層的 BaseDBConfig 中,創建操作類:

public class MutiDBOperate{public string ConnId { get; set; }public string Conn { get; set; }public DataBaseType DbType { get; set; }}

然后把json數據封裝一下:

public static List<MutiDBOperate> MutiConnectionString => MutiInitConn();public static List<MutiDBOperate> MutiInitConn(){List<MutiDBOperate> listdatabase = new List<MutiDBOperate>();string Path = "appsettings.json";using (var file = new StreamReader(Path))using (var reader = new JsonTextReader(file)){var jObj = (JObject)JToken.ReadFrom(reader);if (!string.IsNullOrWhiteSpace("DBS")){var secJt = jObj["DBS"];if (secJt != null){for (int i = 0; i < secJt.Count(); i++){if (secJt[i]["Enabled"].ObjToBool()){listdatabase.Add(SpecialDbString(new MutiDBOperate(){ConnId = secJt[i]["ConnId"].ObjToString(),Conn = secJt[i]["Connection"].ObjToString(),DbType = (DataBaseType)(secJt[i]["DBType"].ObjToInt()),}));}}}}return listdatabase;}}

3、注入服務

這里要說一下,既然是多個庫連接,我就需要一個主庫,就是當前的DB,為了達到切換的目的,我也在配置文件里做了相應的配置:

這個值,就是當前某一個連接對象的ConnId。同時也為了在代碼里能控制這個值,我采用對象靜態類的方式:

namespace Blog.Core.Common.DB {public static class MainDb{//?這個id,就是我們配置文件的idpublic static string CurrentDbConnId = "1";} }

現在我們把剛剛的配置數據對象一起注入到服務里:

/// <summary>/// SqlSugar 啟動服務/// </summary>public static class SqlsugarSetup{public static void AddSqlsugarSetup(this IServiceCollection services){if (services == null) throw new ArgumentNullException(nameof(services));// 把多個連接對象注入服務,這里可以采用Transient瞬態,也可以Scopeservices.AddTransient(o =>{List<ISqlSugarClient> sqlSugarClients = new List<ISqlSugarClient>();var beforeDbConnect = BaseDBConfig.MutiConnectionString;var index = beforeDbConnect.FindIndex(x => x.ConnId == MainDb.CurrentDbConnId);if (index > 0){// 做一個交換,切換主db連接放到第一位var firstDb = beforeDbConnect[0];var changeDb = beforeDbConnect[index];beforeDbConnect[index] = firstDb;beforeDbConnect[0] = changeDb;}beforeDbConnect.ForEach(m =>{sqlSugarClients.Add(new SqlSugarClient(new ConnectionConfig(){ConfigId = m.ConnId,ConnectionString = m.Conn,DbType = (DbType)m.DbType,IsAutoCloseConnection = true,//InitKeyType = InitKeyType.SystemTable}));});return sqlSugarClients;});}}

4、倉儲構造函數注入DB

目前我采用的架構是【service+repository+unitofwork】的模式,所以我們獲取的Db就是ISqlSugarClient實例,那我們就把它注入進去。

在 UnitOfWork 的構造函數中,注入:

private readonly List<ISqlSugarClient> _sqlSugarClients;public UnitOfWork(List<ISqlSugarClient> sqlSugarClients){// 每次取最上邊的db,這個順序已經在注冊服務的時候,切換好了_sqlSugarClient?=?sqlSugarClients[0];??}

5、其他修改

我們修改了db連接方式,那項目啟動時候Seed種子數據的上下文也需要更改一下:

6、做下測試,動態切換

那到底能不能使用呢,這里我們測試一下:

首先我們打開兩個數據庫連接,一個是Sqlite,一個是MSSql,同時我們在兩個各自的博客表中,數據做區分。

我們先執行一下blog查詢,然后把maindb切換成"2"頻道,也就是mssql的:

并不完美,遺留問題

這樣我們每次訪問api,是可以單獨的做控制,但是這里有一個問題,就是我們同一個api內,是無法實現動態切換的目的的,我也在研究,在下篇文章中,我會想辦法解決這個問題。

總結

以上是生活随笔為你收集整理的多库操作:多个数据库的动态切换(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。