$cfg_dbtype = mysql_多库操作2:终于实现多个数据库操作

publicUnitOfWork( ISqlSugarClient sqlSugarClient){_sqlSugarClient = sqlSugarClient;}

//获取DB,保证唯一性//publicSqlSugarClient GetDbClient( ){// 必须要as,后边会用到切换数据库操作return_sqlSugarClient asSqlSugarClient;}

publicvoidBeginTran( ){GetDbClient.BeginTran;}

publicvoidCommitTran( ){try{GetDbClient.CommitTran; //}catch(Exception ex){GetDbClient.RollbackTran;throwex;}}

publicvoidRollbackTran( ){GetDbClient.RollbackTran;}

}

如果修改好了,工作单元,记得也要修改要工作单元接口。

4

动态获取 _db 实例

在上边,我们在工作单元uow(unitOfWork)中,注入了数据库实例,那现在就要获取这个实例了,很简单,直接基类仓储BaseRepository.cs构造函数中,依赖注入我们的IUnitOfWork接口:

privateSqlSugarClient _dbBase;publicBaseRepository(IUnitOfWork unitOfWork){_unitOfWork= unitOfWork;_dbBase= unitOfWork.GetDbClient;}

获取到这个 _dbBase 以后,其实这个时候已经可以了,我们就可以任意的使用这个db实例,但是我们今天的目的是要动态切换,重头戏来了,既然我们每次请求都需要这个db,那简单,我们就修改它的属性:

privateISqlSugarClient _db{get{/* 如果要开启多库支持,* 1、在appsettings.json 中开启MutiDBEnabled节点为true,必填* 2、设置一个主连接的数据库ID,MainDB,必填*/if(Appsettings.app( newstring[] { "MutiDBEnabled"}).ObjToBool){// 默认会获取当前Model的特性,看看是否配置了连接db的ConnIDif( typeof(TEntity).GetTypeInfo.GetCustomAttributes( typeof(SugarTable), true).FirstOrDefault(( x=>x.GetType == typeof(SugarTable))) is SugarTable sugarTable){_dbBase.ChangeDatabase(sugarTable.TableDeion.ToLower);}else{// 如果不存在,则表明当前Model是主数据库操作// 这个配置的地点,看文章上边第二节,注入服务的时候_dbBase.ChangeDatabase(MainDb.CurrentDbConnId.ToLower);}}return_dbBase;}}

5

实体类和连接字符串的配置

首先呢,我们需要在appsettings.json中,配置多个库的连接字符串,注意,如果想要打开多个,就要把那几个的Enabled全部设置为true:

"MainDB": "WMBLOG_SQLITE", // 当前主库的连接字符串,不填写的话,默认是下边true的第一个"MutiDBEnabled": false, // 是否开启多库,默认是false"DBS": [/*MySql = 0,SqlServer = 1,Sqlite = 2,Oracle = 3,PostgreSQL = 4*/{"ConnId": "WMBLOG_SQLITE","DBType": 2,"Enabled": true,"Connection": "WMBlog.db"//只写数据库名就行,我会拼接字符串},{"ConnId": "WMBLOG_MSSQL","DBType": 1,"Enabled": true,"Connection": "Server=.;Database=WMBlogDB;User ID=sa;Password=123;","ProviderName": "System.Data.SqlClient"},{"ConnId": "WMBLOG_MYSQL","DBType": 0,"Enabled": false,"Connection": "Server=localhost; Port=3306;Stmt=; Database=wmblogdb; Uid=root; Pwd=456;"},{"ConnId": "WMBLOG_ORACLE","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=(DEION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.8.65)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME = orcl)))"}],

然后我们修改一下Model,配置SugarTable特性,第一个参数是表明,第二个是对应的db连接字符串的ConnID,这里我们用密码表做测试:

//密码库表///[ SugarTable( "PasswordLib", "WMBLOG_MSSQL")]publicclassPasswordLib{[ SugarColumn(IsNullable = false, IsPrimaryKey = true, IsIdentity = true)]publicintPLID { get; set; }}

到了这里,我们就可以随意的做多库操作了。

我们看看效果吧。

6

实现操作两个数据库效果

首先,开启多库配置:

e486591bad89031b0f9458377b46482f.png

我们测试两个数据库,一个是Sqlite主库,一个是Sqlserver从库,

从主库中,获取博客信息,从库中获取密码表信息,就是刚刚我们在上边配置的实体。

//测试多库连接//[ HttpGet( "TestMutiDBAPI")][ AllowAnonymous]publicasyncTask< object> TestMutiDBAPI( ){// 从主库(Sqlite)中,操作blogsvarblogs = await_blogArticleServices.Query(d => d.bID == 1);// 从从库(Sqlserver)中,获取pwdsvarpwds = await_passwordLibServices.Query(d => d.PLID > 0;

returnnew{blogs,pwds};}

为了做对比效果,我把这两个表,从数据库中删掉,也就是blog在从库中删掉,pwd在主库中删掉:

34b609331ed48a5ebbb4fe83bba58d36.png

我们做一个动图,来看看效果:

abe7a149f6c60a64709a08f4f23fe153.gif

尽管两个表在对方的数据库不存在,但是我们还是获取到了数据:

c7b6cb0b33c1145a4fd7b9d66008acbf.png

那是不是这样就高枕无忧了呢,别慌!咱们是事务不会被破坏吧!来再试试。

7

检验事务操作是否正常

项目中有一个测试接口,大概意思就是先读取一个表数据,然后添加一条数据,中间制造一个异常,最后做回滚操作,看看是否添加的数据被删掉。

[ HttpGet]publicasyncTask> Get{List< string> returnMsg = newList< string> { };try{returnMsg.Add( $"Begin Transaction");_unitOfWork.BeginTran;varpasswords = await_passwordLibServices.Query(d=>d.IsDeleted== false);returnMsg.Add( $"first time : the count of passwords is : {passwords.Count}");

returnMsg.Add( $"insert a data into the table PasswordLib now.");varinsertPassword = await_passwordLibServices.Add( newPasswordLib{IsDeleted = false,plAccountName = "aaa",plCreateTime = DateTime.Now});

passwords = await_passwordLibServices.Query(d => d.IsDeleted == false);returnMsg.Add( $"second time : the count of passwords is : {passwords.Count}");returnMsg.Add( $" ");

//......

varguestbooks = await_guestbookServices.Query;returnMsg.Add( $"first time : the count of guestbooks is : {guestbooks.Count}");

intex = 0;returnMsg.Add( $"There's an exception!!");returnMsg.Add( $" ");intthrowEx = 1/ ex;

varinsertGuestbook = await_guestbookServices.Add( newGuestbook{username = "bbb",blogId = 1,createdate = DateTime.Now,isshow = true});

guestbooks = await_guestbookServices.Query;returnMsg.Add( $"first time : the count of guestbooks is : {guestbooks.Count}");returnMsg.Add( $" ");

_unitOfWork.CommitTran;}catch(Exception){_unitOfWork.RollbackTran;varpasswords = await_passwordLibServices.Query;returnMsg.Add( $"third time : the count of passwords is : {passwords.Count}");

varguestbooks = await_guestbookServices.Query;returnMsg.Add( $"third time : the count of guestbooks is : {guestbooks.Count}");}

returnreturnMsg;}

动图太大,这么不放了,肯定是正确的,直接看结果吧:

a0bbd433d43a37a35e825d29ef62fb3e.png

打完收工!距离微服务又近了一步。

"

每一个努力的,或者正在努力的人,都应该值得被尊重。

——老张的哲学

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值