一、前言

感觉很久没写文章了,最近也比较忙,写的相对比较少,抽空分享基于Dapper 的分库分表开源框架core-data的强大功能,更好的提高开发过程中的效率;

在数据库的数据日积月累的积累下,业务数据库中的单表数据想必也越来越大,大到百万、千万、甚至上亿级别的数据,这个时候就很有必要进行数据库读写分离、以及单表分多表进行存储,提高性能,但是呢很多人不知道怎么去分库分表,也没有现成的分库分表的成熟框架,故不知道怎么下手,又怕影响到业务;现在我给大家推荐core-data的分库分表开源框架。框架开源地址:https://github.com/overtly/core-data

二、基础

2.1 回顾

这里先来回顾下我上一篇文章中的技术栈路线图,如下:

今天从这张技术栈图中来详细分享一切的基础数据库底层操作ORM。

2.2 core-data主要优势:

上一篇文章.Net 微服务架构技术栈的那些事 中简单的介绍了core-data主要优势,如下:

官方建议使用DDD 领域驱动设计思想开发

支持多种数据库(MySql / SqlServer / SQLite ),简单配置添加链接的配置即可

支持分表操作,自定义分表策略的支持

支持表达式方式编写,减少写Sql语句机械性工作

可对Dapper 进行扩展

性能依赖于Dapper 本身的性能,Dapper 本身是轻量级ORM ,官方测试性能都强于其他的ORM

框架支持Framework4.6 - NetStandard 2.0

三、实战详解

这里都仅仅分享核心的内容代码,不把整个代码贴出来,有需要完整Demo源代码请访问 https://github.com/a312586670/NetCoreDemo

在我的解决方案的项目中 引用overt.core.data nuget包,如下图:

3.1 单表模式

创建用户实体代码如下:

///

/// 标注数据库对应的表名

///

[Table("User")]

public class UserEntity

{

///

/// 主键ID,标注自增ID

///

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]

public int UserId { get; set; }

///

/// 商户ID

///

public int MerchantId { set; get; }

///

/// 用户名

///

public string UserName { get; set; }

///

/// 真实姓名

///

public string RealName { get; set; }

///

/// 密码

///

public string Password { get; set; }

///

/// 添加时间

///

public DateTime AddTime { get; set; }

}

代码中通过[Table("User")] 来和数据库表进行映射关联;

通过[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 标注自增主键.

3.2 默认分表策略

从单表模式改成分表模式,并且按照商户的模式进行分表,代码实体代码改造如下:

///

/// 标注数据库对于的表名

///

[Table("User")]

public class UserEntity

{

///

/// 主键ID,标注自增ID

///

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]

public int UserId { get; set; }

///

/// 商户ID

///

[Submeter(Bit =2)]

public int MerchantId { set; get; }

///

/// 用户名

///

public string UserName { get; set; }

///

/// 真实姓名

///

public string RealName { get; set; }

///

/// 密码

///

public string Password { get; set; }

///

/// 添加时间

///

public DateTime AddTime { get; set; }

}

代码中 MerchantId 字段上添加了[Submeter(Bit =2)]标注,并且指定了Bit=2,将会分成根据MerchantId字段取二进制进行md5 hash 取前两位分成256张表

分表模式源码分析

分表模式可以通过在字段上标注Submeter属性,我们先来看看框架对于这个标注的源代码,源代码如下:

///

/// 分表标识

///

public class SubmeterAttribute : Attribute

{

///

/// 16进制位数

/// 1 16

/// 2 256

/// 3 4096

/// ...

///

public int Bit { get; set; }

}

开源框架中其中一个获得分表的表名称的扩展方法,仅仅只贴了一个扩展方法,有兴趣的可以下载开源框架进行源码阅读。

///

/// 获取表名

///

/// 实体实例

///

///

public static string GetTableName(this TEntity entity, Func tableNameFunc = null) where TEntity : class, new()

{

if (tableNameFunc != null)

return tableNameFunc.Invoke();

var t = typeof(TEntity);

var mTableName = t.GetMainTableName();

var propertyInfo = t.GetProperty();

if (propertyInfo == null) // 代表没有分表特性

return mTableName;

// 获取分表

var suffix = propertyInfo.GetSuffix(entity);

return $"{mTableName}_{suffix}";

}

///

/// 获取后缀(默认根据SubmeterAttribute 标注的位数进行Md5 hash 进行分表)

///

///

///

///

internal static string GetSuffix(string val, int bit = 2)

{

if (string.IsNullOrEmpty(val))

throw new ArgumentNullException($"分表数据为空");

if (bit <= 0)

throw new ArgumentOutOfRangeException("length", "length必须是大于零的值。");

var result = Encoding.Default.GetBytes(val.ToString()); //tbPass为输入密码的文本框

var md5Provider = new MD5CryptoServiceProvider();

var output = md5Provider.ComputeHash(result);

var hash = BitConverter.ToString(output).Replace("-", ""); //tbMd5pass为输出加密文本

var suffix = hash.Substring(0, bit).ToUpper();

return suffix;

}

源代码中通过SubmeterAttribute 特性进行对字段进行标注分表,可以传对应的bit参数进行框架默认的分表策略进行分表,但是很多情况下我们需要自定义分表策略,那我们应该怎么去自定义分表策略呢?我们先等一下来实践自定义分表策略,先来创建用户的Repository,代码如下

IUserRepository:

public interface IUserRepository : IBaseRepository

{

}

需要继承IBaseRepository的接口,该接口默认实现了基本的方法,开源框架中IBaseRepository代码方法如下图:

创建完IUserRepository接口后,我们来创建它的实现UserRepository,代码如下:

public class UserRepository : BaseRepository, IUserRepository

{

public UserRepository(IConfiguration configuration)

: base(configuration, "user")

{

}

}

从代码中UserRepository类继承了BaseRepository类,我们来看看这个abstract类的基本结构,如下图:

开源框架中BaseRepository抽象类继承了PropertyAssist类,我们再来看看它的有哪些方法,如下图:

从图中可以看到定义了一系列的virtual方法,那既然是virtual方法我们就可以进行重写

CreateScriptFunc:自动创建脚本数据表方法

TableNameFunc:可以进行自定义分表策略

3.3 自定义分表策略

我们来实现上面提出的自定义分表策略问题(根据商户Id来进行分表,并且自动把不存在的表进行初始化创建),代码改造如下:

IUserRepository:

public interface IUserRepository : IBaseRepository

{

int MerchantId { set; get; }

}

UserRepository 代码改造如下:

public class UserRepository : BaseRepository, IUserRepository

{

public UserRepository(IConfiguration configuration)

: base(configuration, "user")

{

}

///

/// 用于根据商户ID来进行分表

///

public int MerchantId { set; get; }

//自定义分表策略

public override Func TableNameFunc => () =>

{

var tableName = $"{GetMainTableName()}_{MerchantId}";

return tableName;

};

//自动创建分表的脚本

public override Func CreateScriptFunc => (tableName) =>

{

//MySql

return "CREATE TABLE `" + tableName + "` (" +

" `UserId` int(11) NOT NULL AUTO_INCREMENT," +

" `UserName` varchar(200) DEFAULT NULL," +

" `Password` varchar(200) DEFAULT NULL," +

" `RealName` varchar(200) DEFAULT NULL," +

" `AddTime` datetime DEFAULT NULL," +

" `MerchantId` int(11) NOT NULL," +

" PRIMARY KEY(`UserId`)" +

") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4; ";

};

}

3.4 数据库读写分离

我们再来看看开源框架的基类代码结构截图,如下:

对于查询的基本常用的方法都有一个isMaster=false的参数,该参数就是用于是否读取主库,用于基本的主从数据库的分离,也就是读写分离,那改怎么配置读写分离数据库呢

链接字符串如下图:

分别指定了主从数据库的链接字符串.

我们来分析源代码,核心框架源代码如下:

///

/// 连接配置信息获取

/// 1. master / secondary

/// 2. xx.master / xx.secondary

///

public class DataSettings

{

#region Static Private Members

static readonly string _connNmeOfMaster = "master";

static readonly string _connNameOfSecondary = "secondary";

static readonly string _connNameOfPoint = ".";

static string _connNameOfPrefix = "";

#endregion

#region Private Member

///

/// 主库

///

private string Master

{

get { return $"{_connNameOfPrefix}{_connNmeOfMaster}"; }

}

///

/// 从库

///

private string Secondary

{

get

{

return $"{_connNameOfPrefix}{_connNameOfSecondary}";

}

}

#endregion

///

/// 获取链接名称

///

///

/// 不能包含点

///

private string Key(bool isMaster = false, string store = "")

{

_connNameOfPrefix = string.IsNullOrEmpty(store) ? "" : $"{store}{_connNameOfPoint}";

var connName = string.Empty;

if (isMaster)

connName = Master;

else

connName = Secondary;

return connName;

}

}

代码中根据isMaster 参数来进行读写数据库链接参数的获取,以达到读写分离的功能,同时还支持前缀的配置支持,也开源自由配置多个数据库进行读取,只需要构造函数中获取配置即可。

上面的分表Demo 单元测试运行后的结果例子如下图:

已经按照MerchantId 字段进行分表

三、总结

到这里用户表已经根据商户ID进行分表存储了,这样就做到了读写分离及自定义分表策略存储数据,core-data 开源框架还支持更多的强大功能,实现了一系列的基础CRUD的方法,不用写任何的sql语句,Where表达式的支持,同时可以自定义复杂的sql语句,更多请访问框架开源地址:https://github.com/overtly/core-data.

完整的Demo 代码 已经放在github上,Demo代码结构图如下:

地址:https://github.com/a312586670/NetCoreDemo

原创不易,觉得对你有帮助请给一个赞

net core mysql开源框架_.net core 基于Dapper 的分库分表开源框架(core-data)相关推荐

  1. dapper框架_.net core 基于Dapper 的分库分表开源框架(core-data)

    一.前言 感觉很久没写文章了,最近也比较忙,写的相对比较少,抽空分享基于Dapper 的分库分表开源框架core-data的强大功能,更好的提高开发过程中的效率: 在数据库的数据日积月累的积累下,业务 ...

  2. .net core 基于Dapper 的分库分表开源框架(core-data)

    一.前言 感觉很久没写文章了,最近也比较忙,写的相对比较少,抽空分享基于Dapper 的分库分表开源框架core-data的强大功能,更好的提高开发过程中的效率:在数据库的数据日积月累的积累下,业务数 ...

  3. 开源分布式数据库中间件MyCat架构简介(二)——基于MyCat的分库分表,读写分离,水平切分和垂直切分实现原理

    目录 前言 基于MyCat的分库分表,读写分离,水平切分和垂直切分实现原理 一.关于Mycat 二.Mycat 实现原理 三.MyCat 应用场景 四.MyCat 未来展望 五.Mycat 中相关概念 ...

  4. 开源分布式数据库中间件MyCat架构简介(一)——基于MyCat的分库分表,读写分离,水平切分和垂直切分实现原理

    目录 前言 开源分布式数据库中间件MyCat架构简介--MyCat源起 一.数据库切分概述:OLTP和OLAP 二.关系型数据库和NoSQL数据库 三.关系型数据库和NoSQL数据库的特点及优缺点 1 ...

  5. 主从复制MySQL的安装和用数据库中间件MyCat实现分库分表、读写分离

    1.MySql主从复制 1.1.安装mysql 1.1.1.下载 下载地址:https://dev.mysql.com/downloads/mysql/ 1.1.2.卸载预装mysql #查看已安装: ...

  6. docker二进制安装mysql_Docker搭建MySQL读写分离主从模式 分布式数据库中间件Mycat分库分表应用...

    一.MySQL读写分离主从模式 1. 下载镜像 docker pull mysql 当前最新版本:mysql Ver 8.0.19 for Linux on x86_64 (MySQL Communi ...

  7. MySQL高性能:索引、锁、事务、分库分表如何撑起亿级数据

    最近项目增加,缺人手,面试不少,但匹配的人少的可怜.跟其他组的面试官聊,他也抱怨了一番,说候选人有点儿花拳绣腿,回答问题不落地,拿面试最常问的MySQL来说,并不只是懂"增删改查" ...

  8. mysql数据库分表备份脚本_MySQL分库分表备份脚本

    MySQL分库分表备份脚本 vim /data/mysqlback.sh #! /bin/bash BAKPATH=/data/mysql-back MYUSER=root MYPASS=" ...

  9. Mycat - 数据库分库分表中间件,国内最活跃的、性能最好的开源数据库中间件

    转载自 Mycat - 数据库分库分表中间件,国内最活跃的.性能最好的开源数据库中间件 Mycat是什么 Mycat - 数据库分库分表中间件,国内最活跃的.性能最好的开源数据库中间件! 一个彻底开源 ...

  10. 高性能高可用MySQL(主从同步,读写分离,分库分表,去中心化,虚拟IP,心跳机制)

    高性能高可用MySQL(主从同步,读写分离,分库分表,去中心化,虚拟IP,心跳机制) 视频地址:https://www.bilibili.com/video/BV1ry4y1v7Tr?p=8& ...

最新文章

  1. BABOK - 企业分析(Enterprise Analysis)概要
  2. php 数组元素往后移动,php 二维数组 元素移动
  3. ubuntu之apache正向代理及反向代理(ProxyPass\ProxyPassReverse)
  4. Flutter 开发应用第一个页面
  5. 时间都去哪儿了之Python程序测试与优化
  6. js改变style中的值
  7. 【面试题】---前端需要掌握的知识点-----更新...
  8. jQuery中的日期时间控件
  9. html5json转换为数组,Json转数组 在线
  10. 范德蒙行列式计算以应用
  11. GitHub上点击量破百万的宝藏级Spring,讲解的太到位了
  12. java mysql utc时间_Java项目统一UTC时间方案
  13. 前世回忆:放生洒甘露水的重要
  14. 自学java到可以找工作要多久_自学编程需要多久才能找到工作?
  15. 人工神经网络—神经元的数学模型
  16. java:调节图片透明度(支持透明背景)
  17. MarkDown 内部跳转链接
  18. 数字图像学笔记——7. 噪音生成(泊松噪音生成方法)
  19. vue下载pdf为空问题解决
  20. matlab仿真四轮abs,ABS系统的simulink的仿真。

热门文章

  1. C4996 'sprintf': This function or variable may be unsafe.
  2. java二级 计算复杂利息_java 计算存款利息
  3. mysql十三期_《叶问》第13期
  4. verilog幂次方_Verilog学习笔记——有符号数的乘法和加法
  5. guava 的重试机制 guava-retrying 使用
  6. [vue-router] Duplicate named routes definition: { name: “XXX“, path: “XXX“ }
  7. java内存结构不包含堆,JVM之详细分析java内存结构模型
  8. 终于会用c#中的delegate(委托)和event(事件)了
  9. ASP.NET Core 基础教程总结 - ASP.NET Core 基础教程 - 简单教程,简单编程
  10. 09、多线程(一) -- 基本概念