轻量级ORM框架 QX_Frame.Bantina(一、框架简介)
轻量级ORM框架QX_Frame.Bantina系列讲解(开源)
一、框架简介 http://www.cnblogs.com/qixiaoyizhan/p/7417467.html
二、框架使用方式介绍 http://www.cnblogs.com/qixiaoyizhan/p/7418058.html
三、框架性能对比 近期补充
【前言】
ORM(Object Relational Mapping)框架采用元数据来描述对象一关系映射细节,框架根据对象之间的关系以及对象自身的属性可以框架内部自动生成sql语句,简化了程序员的sql开发,极大地提升了编码效率,同时也使得程序错误代码的发生率降低,提高程序的可读性,在使用上相较传统的DAO Sql语句的写法有极大的优势。
任何优秀的新事物都是一把双刃剑,有利就有弊,关键看使用这把剑的人如何去操作。不尽其然,ORM框架也是有碧如执行比较慢缺点,但是舍弃性能的同时提升开发效率,某些程度上也是可以广为接受的,因此,ORM开发的重点又突出在了易使用和高性能两个方面。
今天,我这里推出一款本人花费一周时间独立开发的ORM框架:Bantina 第一版
该框架采用特性的方式做数据表关系映射,吸纳了Microsoft的EntityFramework的一些思想,并且简化了EntityFramework的功能,同时极力向原生的sql语句靠拢,以提高程序执行效率。自带缓存的支持提升查询效率,作为Bantina第一版,我们先暂时支持SqlServer数据库的操作,在后续的版本升级中,逐步开放对Mysql、Oracle甚至是NoSql的支持。
下面我们对Bantina 1.0 做详细介绍。
介绍之前,我们先在本地创建一个数据库,作为演示使用实例以及数据库查询对比的操作对象,该数据库结构如下图所示:

数据库名:DB_QX_Frame_Test
其中包含三张表:TB_ClassName (班级名称)
TB_People (人员表)
TB_Score (分数表)
表之间的关系是TB_People中有TB_ClassName的外键
【框架功能特性】
我们先对Bantina1.0 ORM框架支持的功能做列表介绍,突出框架封装的简单操作方法以及框架支持的简介操作的特性。
1、框架采用继承使用的方式,沿袭了EntityFramework的初始化方法
数据库实体类继承自框架Bantina,然后在构造方法里面提供数据库连接字符串,有多种参数可供选择。
public class DB_QX_Frame_Test : Bantina
{
public DB_QX_Frame_Test() : base("data source=.;initial catalog=DB_QX_Frame_Test;persist security info=True;user id=Sa;password=Sa123456;MultipleActiveResultSets=True;App=EntityFramework") { }
}
2、数据库读写分离的支持
在数据库初始化的同时,传入的数据库连接字符串可以进行读写库的分离设置,极大方便了数据库读写分离的操作(框架原生支持读写分离)。

如果传递单条连接字符串,那么读写库使用一个,相当于关闭读写分离。
3、特性标签的方式标记实体类
该特性沿袭了EntityFramework的特点,但是并不一定追求实体类一定要和数据库结构完全一致,不存在匹配一致性检测,所有的数据库表字段使用特性标签的方式标记识别。
在主外键上,直接将外键表的属性添加进主表即可,并添加标签[ForeignTable]声明外键表即可。
[Table(TableName = "TB_People")]
public class TB_People
{
[Key]
public Guid Uid { get; set; }
[Column]
public string Name { get; set; }
[Column]
public int Age { get; set; }
[Column]
[ForeignKey]
public int ClassId { get; set; }
[ForeignTable]
public TB_ClassName TB_ClassName { get; set; }
}
[Table(TableName = "TB_ClassName")]
public class TB_ClassName
{
// PK(identity)
[Key]
public Int32 ClassId { get; set; }
//
[Column]
public String ClassName { get; set; }
}
这里标签Table可以支持数据库的表名和实体类的表名不一致,在参数TableName声明数据库真实的表名即可。
在alpha版本里,字段也是支持修改并配置的,但是为了支持后续的特性Lambda表达式参数,将此功能去掉,以便简化框架代码,因此,字段名称是需要类属性和表的字段完全一致的情况下进行操作的。
这里字段的标签Key以及Column也是有必要的,在后续的使用中会进行逐步讲解。这里大家可能会有疑问,每个属性手动写标签会比较多,比较麻烦,这里有专门匹配的代码生成器进行生成,避免了手动添加的繁琐。
4、框架自带智能缓存特性
Sql查询的耗时主要出现在大量数据的查询上,一套系统如果没有良好的设计,每次获取数据都要进行大量耗时查询操作,那么系统的用户体验感将会降到极低,直接影响到了用户的使用心情。
Bantina框架原生自带了缓存特性,在对数据库的查询操作时,并不会直接对所有数据进行缓存,只会对当前的查询操作执行的结果进行缓存,当对操作的表进行增删改操作时,又会智能识别下次重新获取数据并覆盖缓存。这样避免了全表数据缓存查询的耗时时间,又能在数据查询的缓存支持上得到很好的效率。
缓存的智能消除,极力维护了系统数据一致性,避免了等待缓存过期造成的数据尴尬问题。
这里查询同一组集合数据的三段同样的代码耗时展示(单位:毫秒):

可以看出,第一次是从数据库进行获取数据,并添加到缓存,第二次和第三次是从缓存中获取的数据,速度非常快;
5、提供多种常用执行方法,无需后续数据格式转化以及遍历操作
原生支持各种常用查询结果,不需要后续进行遍历等格式转化操作,一切以对象及集合说话,完全符合面向对象行为方式。

这里的Query查询方法包含了Entity<T>单个实体对象的查询以及Entities<T>多个实体对象List列表的查询。
TEntity QueryEntity<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class; List<TEntity> QueryEntities<TEntity>() where TEntity : class; List<TEntity> QueryEntities<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class;
这里我展示Bantina常用的方法接口:
public interface IBantina
{
Task<bool> Add<TEntity>(TEntity entity) where TEntity : class;
Task<bool> Update<TEntity>(TEntity entity) where TEntity : class;
Task<bool> Update<TEntity>(TEntity entity, Expression<Func<TEntity, bool>> where) where TEntity : class;
Task<bool> Delete<TEntity>(TEntity entity) where TEntity : class;
Task<bool> Delete<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class;
bool QueryExist<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class;
int QueryCount<TEntity>() where TEntity : class;
int QueryCount<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class;
TEntity QueryEntity<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class;
List<TEntity> QueryEntities<TEntity>() where TEntity : class;
List<TEntity> QueryEntities<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class;
List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, bool isDESC = false) where TEntity : class;
List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, Expression<Func<TEntity, bool>> where, bool isDESC = false) where TEntity : class;
List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, out int count, bool isDESC = false) where TEntity : class;
List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, Expression<Func<TEntity, bool>> where, out int count, bool isDESC = false) where TEntity : class;
DataTable QueryDataTable<TEntity>(string sql, params SqlParameter[] parms) where TEntity : class;
DataSet QueryDataDataSet<TEntity>(string sql, params SqlParameter[] parms) where TEntity : class;
int ExecuteSql<TEntity>(string sql, params SqlParameter[] parms) where TEntity : class;
List<TEntity> ExecuteSqlToList<TEntity>(string sql, params SqlParameter[] parms) where TEntity : class;
int ExecuteStoredProcedure<TEntity>(string storedProcedureName, params object[] parms) where TEntity : class;
List<TEntity> ExecuteStoredProcedureToList<TEntity>(string storedProcedureName, params object[] parms) where TEntity : class;
}
Bantina Method Interface
6、原生自带分页查询
数据库的查询自带分页查询方法,不需要我们后续进行查全部集合后的分页操作,极大地提升了开发的效率。
分页的条件完整全面且易于传递及操作,对程序员的开发有较大的帮助。
List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, bool isDESC = false) where TEntity : class; List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, Expression<Func<TEntity, bool>> where, bool isDESC = false) where TEntity : class; List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, out int count, bool isDESC = false) where TEntity : class; List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, Expression<Func<TEntity, bool>> where, out int count, bool isDESC = false) where TEntity : class;
7、Lambda表达式的支持
对数据集合的查询条件全部统一使用Lambda表达式,便于操作的同时,极大降低了手动拼写错误的风险。
这里的Lambda表达式完全使用标准的Linq风格,在Lambda的支持条件下,查询条件对String类型的字段默认支持一下几种筛选条件:
t.Equals(""); //完全匹配
t.Contains(""); //模糊查询
t.StartWith(""); //模糊查询起始字符固定
t.EndsWith(""); //模糊查询结束字符固定
...
例如我们需要查询People表Name字段包含2的所有数据的数目,操作方法如下图所示:

8、原生SQL语句方式和存储过程的支持
Bantina在提倡框架风格使用的基础上,也提供了对原生SQL语句和存储过程执行的支持,便于适应多变的生产环境。

9、增删改使用Task异步执行的方式
Bantina的增删改操作全部采用异步Task线程执行的方式,提高了程序的执行效率。
在多行数据的批量添加修改删除循环调用的时候,会提升插入操作执行的效率。
默认对异步的支持,也可以使得web服务的响应得到提升,间接提高了用户体验感。
Task<bool> Add<TEntity>(TEntity entity) where TEntity : class; Task<bool> Update<TEntity>(TEntity entity) where TEntity : class; Task<bool> Update<TEntity>(TEntity entity, Expression<Func<TEntity, bool>> where) where TEntity : class; Task<bool> Delete<TEntity>(TEntity entity) where TEntity : class; Task<bool> Delete<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class;
10、对事务操作的支持
Bantina框架封装了对事务的支持,而且调用非常简洁。
只需要数据库上下文对象调用事务方法,然后传递一个委托给方法作为参数执行委托事件即可。
下面我使用了匿名委托的方式进行调用事务执行操作,在委托方法里面分别执行了几组需要支持事务操作的数据库操作,然后方法自动提交事务,如果有事务失败的操作,那么方法会自动回滚操作。
代码展示如下图所示:

11、支持主外键多表关联查询操作
Bantina可以通过配置主外键关系,通过特定的特性标签来标识主外键关系,然后达到主外键关联查询的目的。
配置代码见该介绍第三条 3、特性标签的方式标记实体类
例如我们要支持关联外键表TB_ClassName的查询,并将班级的名称显示,通过配置后,我们可以进行如下查询操作:

查询结果如下图所示:

Bantina实现了如上的关联查询操作方式。
介绍完我们的Bantina框架后,我们将在下一章对Bantina的使用方法进行介绍:
二、框架使用方式介绍 http://www.cnblogs.com/qixiaoyizhan/p/7418058.html
【获取方式】
1、Nuget获取:Nuget搜索 QX_Frame.Helper_DG

2、GitHub查看源代码:https://github.com/dong666/QX_Frame.Helper_DG
3、联系本人获取,联系方式在下方博客签名中,qq、email均可。
轻量级ORM框架 QX_Frame.Bantina(一、框架简介)的更多相关文章
- 轻量级ORM框架 QX_Frame.Bantina(二、框架使用方式介绍)
轻量级ORM框架QX_Frame.Bantina系列讲解(开源) 一.框架简介 http://www.cnblogs.com/qixiaoyizhan/p/7417467.html 二.框架使用方式介 ...
- 轻量级ORM框架Dapper应用一:Dapper安装
一.Dapper简介 Dapper是一款轻量级ORM框架,为解决网站访问流量极高而产生的性能问题而构造,主要通过执行TSQL表达式而实现数据库的CQRS. 如果你在项目中遇到性能访问问题,选择Dapp ...
- 轻量级ORM框架初探-Dapper与PetaPoco的基本使用
一.EntityFramework EF是传统的ORM框架,也是一个比较重量级的ORM框架.这里仍然使用EF的原因在于为了突出轻量级ORM框架的性能,所谓有对比才有更优的选择. 1.1 准备一张数据库 ...
- c# 轻量级ORM框架 实现(一)
发布一个自己写的一个轻量级ORM框架,本框架设计期初基于三层架构.所以从命名上来看,了解三层的朋友会很好理解. 设计该框架的目的:不想重复的写增删改查,把精力放到功能实现上. 发布改框架的原因:希望给 ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之七 || API项目整体搭建 6.2 轻量级ORM
更新 1.在使用的时候,特别是更新数据的时候,如果不知道哪里有问题,可以查看数据库 和 实体类 的字段,是否大小写一致,比如 name 和 Name 2.在使用Sqlsugar 的 CodeFirst ...
- 【从零开始搭建自己的.NET Core Api框架】(三)集成轻量级ORM——SqlSugar:3.1 搭建环境
系列目录 一. 创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...
- .NET轻量级ORM框架Dapper入门精通
一.课程介绍 本次分享课程包含两个部分<.NET轻量级ORM框架Dapper修炼手册>和<.NET轻量级ORM框架Dapper葵花宝典>,阿笨将带领大家一起领略轻量级ORM框架 ...
- 分享自己写的基于Dapper的轻量级ORM框架~
1.说明 本项目是一个使用.NET Standard 2.0开发的,基于 Dapper 的轻量级 ORM 框架,包含基本的CRUD以及根据表达式进行一些操作的方法,目前只针对单表,不包含多表连接操作. ...
- C# 性能优化 之 秒表 Stopwatch。 Dapper一个和petapoco差不多的轻量级ORM框架
Sweet小马 小马同学的编程日记. C# 性能优化 之 秒表 Stopwatch. 生词解释:Diagnostics[,daɪəg'nɑstɪks] n.诊断学 using System.Diagn ...
随机推荐
- JavaScript一个猜数字游戏
效果图: 代码: <body> <script type="text/javascript"> window.onload = newgame; //页面载 ...
- Kindeditor编辑插件的使用
1.首先kindeditor这个插件需要配合着asp.net的自生带的控件textbox来实现 2.首先前台界面代码 <f:FormRow runat="server"> ...
- js中变量的连续赋值
今天遇到了一个连续赋值的经典案例,网友们给出的答案也是五花八门,看起来有些繁琐,我也来说说自己的看法. 下面就是这个经典案例: var a = {n: 1}: var b = a; a.x = a = ...
- Klass与Oop
前段时间,一直在看<Hotspot实战>,顺便编译了一份OpenJDK的源码,然后就在eclipse里面调试起来. 虽然我的入门语言是c/c++,但是被Java拉过来好几年了,现在再看源码 ...
- 华为OJ之自动售货系统
本题主要难点有两部分: 1,找零算法.如何找零应该是最具技巧性的部分,根据已有的硬币金额分布,对应的解决办法可能会有不同.本题中的1,2,5,10这种情况满足贪心性质,故我们简单的用贪心算法的思想来解 ...
- 图像处理与matlab实例之图像平滑(一)
一.何为图像噪声?噪声是妨碍人的感觉器官所接受信源信息理解的因素,是不可预测只能用概率统计方法认识的随机误差. 举个例子: 从这个图中,我们可以观察到噪声的特点:1>位置随机 2>大小不规 ...
- Hybris商品图片导入与压缩有关的配置
1. 在电脑上安装 ImageMagick 软件(windows平台还需要安装VC++),下载路径:http://www.imagemagick.org/script/download.php#w ...
- zTree-已勾选项id传输到action的解决方案
测试jsp <%@ page language="java" contentType="text/html; charset=utf-8" page ...
- 发票OCR识别/票据OCR自动识别
对于一些大的集团公司来说,分散式财务管理模式管理效率不高,管理成本相对较高,同时也制约了集团企业发展战略的实施,因而需要建设财务共享中心.一个企业想建造财务共享中心,面临的难题是大量的数据采集和信息处 ...
- AJAX 中JSON 和JSONP 的区别 以及请求原理
AJAX 跨域请求 - JSONP获取JSON数据 博客分类: Javascript /Jquery / Bootstrap / Web Asynchronous JavaScript and X ...