企业项目实战 .Net Core + Vue/Angular 分库分表日志系统二 | 简单的分库分表设计
教程预览
01 | 前言
02 | 简单的分库分表设计
03 | 控制反转搭配简单业务
04 | 强化设计方案
05 | 完善业务自动创建数据库
06 | 最终篇-通过AOP自动连接数据库-完成日志业务
前言
项目涉及到了一些设计模式,如果你看的不是很明白,没有关系坚持下来,写完之后去思考去品,你就会有一种突拨开云雾的感觉,所以请不要在半途感觉自己看不懂选择放弃,如果我哪里写的详细,或者需要修正请联系我,谢谢。
创建项目
1.SDK安装
我们开发用的vs版本是2019 .Net Core的版本是3.1
下载 SDK 地址 :https://dotnet.microsoft.com/download
2.新建项目
这里选择Core 版本是3.1 项目类型是API
Docker支持我们不勾选,我会在后续给大家单独再开一个系列 我们专讲,慢慢来。
这里可以看到一个非常干净的项目就创建出来了,项目结构就是这样,里面的详情可以去看老张的第二个章节,讲的很明白,我就不在重复了
https://www.cnblogs.com/laozhang-is-phi/p/9495620.html
进阶可以去看开源源码 https://github.com/aspnet/MetaPackages/tree/master/src/Microsoft.AspNetCore
然后我们直接F5 启动项目看看 是不是新建的项目是不是没有问题,项目一切正常,我们开始进入正轨。
项目思考
1.分表
分表这个功能,就是把相同结构不同名称的多张表数据读取出来,这个部分其实很简单,我们常见的ORM都支持切换表名进行查询。
2.分库
分库如何实现呢。
先来看一下我们常用的ORM框架是如何连接数据库的。
SqlSugar连接数据库
FreeSql连接数据库
它们有一个共同点,NEW一个对象传递数据库连接字符串,设置好数据库类型,各自的xxx配置,就会得到一个连接的Client,然后就可以进行CRUD了。
那New多个对象,每个对象都是不同的连接字符串岂不是就可以操作多个数据库了。
大家写代码可别直接在业务/数据访问层这么写,整不好就让你下班领盒饭了。
那么这种情境下因该如何设计能让代码更加规范、易扩展呢!
3.思考
思路就是这样,那么如果让你来设计,你会怎么做呢,大家可以自己尝试着先去根据自己想法设计看看,然后我们下一节,我来给讲解我的设计方案。
设计要求
为了提高难度设计难度我们来同时兼容FreeSql、SqlSugar2款现在最热门的ORM。
我们设计要做到:
易扩展(就算再来一个我也能轻松支持)
切换快(不改动业务代码前提下,2个ORM框架我想用谁就用谁,随便切换)
可共存(可以取2款ORM各自优点在一起开发使用)
实战
1.制定规范
①、我们先新建一个类库 EasyLogger.DbStorage(ps:该类库用于制定规范,提供接口)
②、新建 Interface 文件夹
③、新建泛型接口 IAnyStorage (存储器)
该接口规范字典操作标准方法。
这里使用的ConcurrentDictionary 是一个并发字典。
public interface IAnyStorage<T>
where T : class
{
ConcurrentDictionary<string, T> DataMap { get; }
T GetByName(string name, string defaultName);
void AddOrUpdate(string name, T val);
void Remove(string name);
void Clear();
}
2.遵循规范
我们先做SqlSugar的版本
①、新建 EasyLogger.SqlSugarDbStorage类库
②、新建 Interface 文件夹
③、新建 ISqlSugarProviderStorage (SqlSugar连接提供程序存储器) 接口继承IAnyStorage
继承IAnyStorage因为他是泛型继承它,我们需要传递一个参数,他是什么呢?当然是我们的SqlSugar连接提供程序了。
我们安装NuGet包安装 sqlSugarCore
⑤、新建ISqlSugarProvider (SqlSugar连接提供程序) 接口作为泛型参数传入
⑥、新建Impl 文件夹
⑦、新建 DefaultSqlSugarProviderStorage类继承 ISqlSugarProviderStorage 进行SqlSugar连接提供程序存储器的具体实现
public class DefaultSqlSugarProviderStorage : ISqlSugarProviderStorage
{
public ConcurrentDictionary<string, ISqlSugarProvider> DataMap { get; private set; }
public DefaultSqlSugarProviderStorage(IServiceProvider serviceProvider)
{
DataMap = new ConcurrentDictionary<string, ISqlSugarProvider>();
var tmpDataMap = serviceProvider.GetServices<ISqlSugarProvider>()
.ToDictionary(item => item.ProviderName);
foreach (var item in tmpDataMap)
{
this.AddOrUpdate(item.Key, item.Value);
}
}
public void AddOrUpdate(string name, ISqlSugarProvider val)
{
DataMap[name] = val;
}
public void Clear()
{
DataMap.Clear();
}
public ISqlSugarProvider GetByName(string name, string defaultName)
{
ISqlSugarProvider result = null;
if (name == null)
{
if (!DataMap.TryGetValue(defaultName, out result))
{
throw new Exception("没有找到 DefaultName Provider");
}
return result;
}
else if (DataMap.TryGetValue(name, out result))
{
return result;
}
throw new ArgumentException($"没有找到 {name} Provider");
}
public void Remove(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
return;
}
this.DataMap.TryRemove(name, out ISqlSugarProvider result);
}
}
字典的操作我想都能看明白,基础差的朋友可能会觉得不懂的就是下面这句,这是做什么呢,其实就是我们把注入ISqlSugarProvider的实现都查询
出来,放到我们的DateMap集合中(好处后面我会实践给大家讲到),到此我们SqlSugar连接提供程序存储库就完成了。
var tmpDataMap = serviceProvider.GetServices<ISqlSugarProvider>()
.ToDictionary(item => item.ProviderName);
foreach (var item in tmpDataMap)
{
this.AddOrUpdate(item.Key, item.Value);
}
差点SqlSugar连接提供程序的实现给漏了。
我们在 Impl 文件夹 新建 SqlSugarProvider类,继承ISqlSugarProvider接口。
public class SqlSugarProvider : ISqlSugarProvider
{
public string ProviderName { get; set; }
public SqlSugarClient Sugar { get; set; }
public SqlSugarProvider()
{
this.Sugar = this.CreateSqlSugar();
this.ProviderName = "DefaultSqlSugar";
}
private SqlSugarClient CreateSqlSugar()
{
// todo 临时
var db = new SqlSugarClient(
new ConnectionConfig()
{
ConnectionString = "server=.;uid=sa;pwd=@jhl85661501;database=SqlSugar4XTest",
DbType = DbType.SqlServer,//设置数据库类型
IsAutoCloseConnection = true,//自动释放数据务,如果存在事务,在事务结束后释放
InitKeyType = InitKeyType.Attribute //从实体特性中读取主键自增列信息
});
return db;
}
public void Dispose()
{
this.Sugar.Dispose();
}
}
CreateSqlSugar 方法是我从SqlSugar官方复制过来的,大家注意把ConnectionString改成自己的数据库连接。
我们现在来配置一下 Startup 先看看效果。
感谢 @Damn 帮我发现漏掉说明的代码!
public void ConfigureServices(IServiceCollection services)
{
// 注入
services.AddSingleton<ISqlSugarProvider, SqlSugarProvider>();
services.AddSingleton<ISqlSugarProviderStorage, DefaultSqlSugarProviderStorage>();
services.AddControllers();
}
app.Use(async (context, next) =>
{
var sqlStorage = app.ApplicationServices.GetService<ISqlSugarProviderStorage>();
var sugarClient = sqlStorage.GetByName(null, "DefaultSqlSugar").Sugar;
Console.WriteLine("查看sugarClient");
});
我们成功的从SqlSugar连接提供程序存储中,拿到SqlSugarClient连接。
补充
下面代码是我在技术群里看到使用FreeSql的方式,这么写没有问题简单单例的实现,我推荐大家使用上文中依赖注入的方式来使用!
结尾
回顾一下本节的内容。
1.我们新建统一的泛型 IAnyStorage接口(连接提供程序存储库)来规范调用。
2.我们创建了 ISqlSugarProviderStorage (SqlSugar连接提供程序存储库) 通过继承IAnyStorage来规范接口实现。
3.新建了 ISqlSugarProvider (SqlSugar连接提供程序).
4.我们完善了接口的实现。
5.我们成功在 Startup 中新建一个简单的中间件 成功从SqlSugar连接提供程序存储中,拿到SqlSugarClient连接。
思考问题
我们把数据库连接字符串写在(SqlSugar连接提供程序)合理吗,是不是依赖太深,这个时候我们就用到控制反转来降低依赖性,那么具体怎么做呢!
企业项目实战 .Net Core + Vue/Angular 分库分表日志系统二 | 简单的分库分表设计的更多相关文章
- 企业项目实战 .Net Core + Vue/Angular 分库分表日志系统一 | 前言
教程预览 01 | 前言 02 | 简单的分库分表设计 03 | 控制反转搭配简单业务 04 | 强化设计方案 05 | 完善业务自动创建数据库 06 | 最终篇-通过AOP自动连接数据库-完成日志业 ...
- 企业项目实战 .Net Core + Vue/Angular 分库分表日志系统 | 前言
介绍 大家好我是初久,一名从业4年的.Net开发攻城狮,从今天开始我会和大家一起对企业开发中常用的技术进行分享,一方面督促自己学习,一方面也希望大家可以给我指点出更好的方案,我们一起进步. 项目背景 ...
- 企业项目实战 .Net Core + Vue/Angular 分库分表日志系统 | 简单的分库分表设计
前言 项目涉及到了一些设计模式,如果你看的不是很明白,没有关系坚持下来,写完之后去思考去品,你就会有一种突拨开云雾的感觉,所以请不要在半途感觉自己看不懂选择放弃,如果我哪里写的详细,或者需要修正请联系 ...
- #企业项目实战 .Net Core + Vue/Angular 分库分表日志系统六 | 最终篇-通过AOP自动连接数据库-完成日志业务
教程预览 01 | 前言 02 | 简单的分库分表设计 03 | 控制反转搭配简单业务 04 | 强化设计方案 05 | 完善业务自动创建数据库 06 | 最终篇-通过AOP自动连接数据库-完成日志业 ...
- 企业项目实战 .Net Core + Vue/Angular 分库分表日志系统 | 控制反转搭配简单业务
教程预览 01 | 前言 02 | 简单的分库分表设计 03 | 控制反转搭配简单业务 说明 我们上一节已经成功通过 连接提供程序存储库,获取到了 连接提供程序,但是连接提供程序和数据库连接依赖太深, ...
- 企业项目实战 .Net Core + Vue/Angular 分库分表日志系统五 | 完善业务自动创建数据库
教程预览 01 | 前言 02 | 简单的分库分表设计 03 | 控制反转搭配简单业务 04 | 强化设计方案 05 | 完善业务自动创建数据库 说明 这节来把基础的业务部分完善一下. 因为 IQue ...
- 企业项目实战 .Net Core + Vue/Angular 分库分表日志系统三 | 控制反转搭配简单业务
教程预览 01 | 前言 02 | 简单的分库分表设计 03 | 控制反转搭配简单业务 04 | 强化设计方案 05 | 完善业务自动创建数据库 06 | 最终篇-通过AOP自动连接数据库-完成日志业 ...
- 企业项目实战 .Net Core + Vue/Angular 分库分表日志系统四 | 强化设计方案
教程预览 01 | 前言 02 | 简单的分库分表设计 03 | 控制反转搭配简单业务 04 | 强化设计方案 强化 先来记录一下我们现在的样子,一会好做个对比 1.在EasyLogger.DbSto ...
- vue.js及项目实战[笔记]— 03 vue.js插件
一. vue补充 1. 获取DOM元素 救命稻草,document.querySelector 在template中标示元素`ref = "xxx" 在要获取的时候,this.$r ...
随机推荐
- JavaScript学习系列博客_18_JavaScript中的匿名函数
匿名函数 - 用函数声明的方式创建一个函数时,不加函数名称. function sum(){ console.log("我是函数sum")} - 不加名称,这样写浏览器是会报错的. ...
- Linux内核之 内存管理
前面几篇介绍了进程的一些知识,从这篇开始介绍内存.文件.IO等知识,发现更不好写哈哈.但还是有必要记录下自己的所学所思.供后续翻阅,同时写作也是一个巩固的过程. 这些知识以前有文档涉及过,但是角度不同 ...
- Watchtower - 自动更新 Docker 镜像与容器
git 地址:https://github.com/containrrr/watchtower Docker images docker pull containrrr/watchtower:i386 ...
- VyOS软路由系统基本设置
1. VyOS简介 VyOS是一个开源的网络操作系统,可以安装在物理硬件上,也可以安装在你自己的虚拟机上,或者是一个云平台上.它基于GNU/Linux,并加入了多个应用程序,如:Quagga, ISC ...
- SpringBoot项目 使用Jenkins进行自动化部署 gitlab打tag 生产测试环境使用 含配置中心
脚本 node('master') { def mvnHome = tool 'maven11-free' def gitUrl = "http://gitlab.wdcloud.cc:10 ...
- 第六篇Scrum冲刺博客--Interesting-Corps
第六篇Scrum冲刺博客 站立式会议 1.会议照片 2.队友完成情况 团队成员 昨日完成 今日计划 鲍鱼铭 搜索页面以及音乐详情页面数据导入及测试 各界面数据请求云函数设计及实现 叶学涛 进行页面的优 ...
- 兄弟,你爬虫基础这么好,需要研究js逆向了,一起吧(有完整JS代码)
这几天的确有空了,看更新多快,专门研究了一下几个网站登录中密码加密方法,比起滑块验证码来说都相对简单,适合新手js逆向入门,大家可以自己试一下,试不出来了再参考我的js代码.篇幅有限,完整的js代码在 ...
- Java GUI 图书管理系统
01 概述 一款功能强大的图书馆管理系统,功能齐全,小白/大学生项目实训,学习的不二之选. 02 技术 此系统使用 java awt 实现.java.awt是一个软件包,包含用于创建用户界面和绘制图形 ...
- Mybatis Log plugin 破解!!!
前言 今天重新装了IDEA2020,顺带重装了一些插件,毕竟这些插件都是习惯一直在用,其中一款就是Mybatis Log plugin,按照往常的思路,在IDEA插件市场搜索安装,艹,眼睛一瞟,竟然收 ...
- Windows Server 2012 R2 时间同步
最近的项目两台服务器都是Windows Server 2012的系统,需要做时间同步,现在是一些从网上搜罗的步骤总结. 具体就是配置windows的注册表: 一.服务端配置 (NTP服务器,客户端将根 ...