一、前言

感觉很久没写文章了,最近也比较忙,写的相对比较少,抽空分享基于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】电商平台升级之微服务架构应用实战

  • .Net Core微服务架构技术栈的那些事

  • Asp.Net Core 中IdentityServer4 授权中心之应用实战

  • Asp.Net Core 中IdentityServer4 授权中心之自定义授权模式

  • Asp.Net Core 中IdentityServer4 授权流程及刷新Token

  • Asp.Net Core 中IdentityServer4 实战之 Claim详解

  • Asp.Net Core 中IdentityServer4 实战之角色授权详解

  • Asp.Net Core 中间件应用实战中你不知道的那些事

  • Asp.Net Core Filter 深入浅出的那些事-AOP

  • Asp.Net Core EndPoint 终结点路由工作原理解读

  • ASP.NET CORE 内置的IOC解读及使用

♥ 给个[在看],是对我最大的支持 ♥

orm框架有哪些_.net core 基于Dapper 的分库分表开源框架(coredata)相关推荐

  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多字段分库分表基因码_一文学会常用 MySQL 分库分表方案

    来源 | https://www.cnblogs.com/littlecharacter/p/9342129.html 一.数据库瓶颈 不管是IO瓶颈,还是CPU瓶颈,最终都会导致数据库的活跃连接数增 ...

  6. 基于SpringCloud实现Shard-Jdbc的分库分表模式,数据库扩容方案

    一.项目结构 1.工程结构 2.模块命名 shard-common-entity: 公共代码块 shard-open-inte: 开放接口管理 shard-eureka-7001: 注册中心 shar ...

  7. 架构组件:基于Shard-Jdbc分库分表,数据库扩容方案

    架构组件:基于Shard-Jdbc分库分表,数据库扩容方案 一.数据库扩容 1.业务场景 互联网项目中有很多"数据量大,业务复杂度高,需要分库分表"的业务场景. 这样分层的架构 ( ...

  8. 数据库查询某一列大写转化小写字母表示_基于MySQL数据库下亿级数据的分库分表...

    每天给你诚意满满的干货 本文来自程序之心知乎专栏收到的投稿 作者:恒生研究院 移动互联网时代,海量的用户数据每天都在产生,基于用户使用数据等这样的分析,都需要依靠数据统计和分析,当数据量小时,数据库方 ...

  9. 基于代理的数据库分库分表框架 Mycat实践

    192.168.199.75 MySQL . MyCAT master 192.168.199.74 MySQL slave 192.168.199.76 MySQL standby master 如 ...

  10. 数据库分库分表(sharding)系列(三) 关于使用框架还是自主开发以及sharding实现层面的考量...

    当团队对系统业务和数据库进行了细致的梳理,确定了切分方案后,接下来的问题就是如何去实现切分方案了,目前在sharding方面有不少的开源框架和产 品可供参考,同时很多团队也会选择自主开发实现,而不管是 ...

最新文章

  1. 图解谷歌大脑丶城市大脑丶全球脑与互联网大脑的关系
  2. Struts2+Hibernate+Spring 整合示例
  3. Google要推输入法 是战略布局还是战术需要?
  4. 指纹浏览器 开源 linux,浏览器指纹--Canvas指纹
  5. 神经网络与机器学习 笔记—卷积神经网络(CNN)
  6. 企业管理软件能带来什么
  7. EasyNetQ介绍
  8. 【Linux】一步一步学Linux——wget命令(192)
  9. 什么变量在堆内存里存放,什么变量在栈内存里存放
  10. [课程相关]homework-06
  11. coroutine资源索引
  12. jQuery全屏滚动插件fullPage.js
  13. php eureka客户端,Spring Cloud(一)配置Eureka 服务器(示例代码)
  14. iOS UIScrollView和缩放
  15. python可变参数之*args和*kwargs学习回顾
  16. 计算机数据采集管理系统的结构和功能,计算机数据采集系统简介
  17. react项目中使用echart
  18. MySQL模糊查询like优化,再也用不着 like+% 了
  19. Xdebug中文文档-基础特性
  20. 为什么 MySQL 执行完 Delete 操作之后,空间没有释放?

热门文章

  1. ubuntu下用户的创建、修改
  2. error CS1617: Invalid option 'latest' for /langversion; must be ISO-1, ISO-2, Default or an...
  3. opencv获取mat的指针_opencv中Mat类型数据操作与遍历
  4. linux引导界面含义,Linux引导时输入特殊信息的含义的方法
  5. 消防信号二总线有没电压_杭后旗医院消防消防设备电源原理
  6. 用python股票_十分钟学会用Python交易股票
  7. Mysql的sql语句基础大全,仅供个人笔记参考,由于创建过程只求速度,所以结构比较乱,请不要打开,如有需要,请自行查阅其他文献
  8. DOM之节点操作总结(附实例、图解)
  9. swagger整合springMVC
  10. 属性篇(3)—If you love css …