分享自己的超轻量级高性能ORM数据访问框架Deft
Deft 简介
Deft是一个超轻量级高性能O/R mapping数据访问框架,简单易用,几分钟即可上手。
Deft包含如下但不限于此的特点:
1、按照Transact-SQL的语法语义风格来设计,只要调用者熟悉基本的Transact-SQL语法即可瞬间无忧开码,大大降低了学习Deft的成本,甚至零成本。
2、性能十分不错(个人觉得易用性很重要,只要性能不拖后腿就好了),通过缓存+Emit反射IDataReader,极速获取List<T>。
3、强大的查询功能,支持使用Lambda表达式任意组装where条件,支持各种各样的运算符和括号优先级,支持给查询字段取别名。
4、支持SQLServer、MySQL、Oracle、SQLite等多数据库类型,同时也支持一个业务系统里面存在多个数据库。
5、支持事务、分页查询、排序等。
6、支持like,in等sql操作符,支持avg,count,max,min,sum等sql函数。
7、颜值高,整套语法接口设计的十分巧妙,支持Lambda 表达式,链式编程,任意组装sql,极度美观。
8、支持手写sql, List<T> Select<T>(string sql)。
9、各种映射能力,包括任意查询的结果映射,支持dynamic。
10、实体类非常简单,手写即可,不需要借助工具,也没有特性标记或者继承BaseEntity等杂七杂八的东西。
11、参数化赋值,防止sql注入。
12、开放DbHelper,满足特定使用场景(比如考勤报表),可以直接执行成百上千行的复杂sql。
13、对象化操作,编译时检查。使用Lambda 表达式做写入操作时,只会对表达式指定的字段做写入操作。
14、调用代码极其简单,干净清爽,可读性强,方便维护。
15、对外抛出OnDbExecute事件,调用方可自行处理日志埋点、sql监控等。
16、开发效率快,基本无配置,无工具支持也可以开发。
17、超轻量、体积小。
18、......等您来发现
不需要xxx入门系列,不需要xxx开发文档,不需要xxx使用教程,不需要繁琐的配置,不需要晦涩难懂的使用方式,不需要xxx。。。一切从简。
因为Deft的设计使用初衷就是一个初学者花30秒钟配置数据库连接信息,然后花3分钟扫一眼和Transact-SQL极度相似的链式语法就可以做到对数据库的访问。
编译后的Release版本只有59KB
为什么叫Deft?
Deft 核心类介绍
Deft共计有4个核心类
Jugg 用于对外提供ORM核心方法的静态类
JuggContext 用于对外提供ORM核心方法的实例类
JuggDbHelper 用于数据库访问的帮助类
JuggConfig 用于设置一些配置项的静态类
Jugg一词来源于游戏中的剑圣,是一个敏捷且攻击属性都很强的战斗英雄
Deft 3分钟即可上手使用
实体类
public class UserInfo
{
public Int32 Id { get; set; } public String Name { get; set; } public Byte? Age { get; set; } public Byte? Sex { get; set; } public String Email { get; set; } public String Address { get; set; } public String Remark { get; set; } public Object Test { get; set; } //无意义字段
}
.config文件中配置数据库连接信息
硬编码也可以配置数据库连接信息,遵守约定大于配置
JuggConfig.DefaultDbConCfg = new ConnectionStringSettings { ProviderName = "System.Data.SqlClient", ConnectionString = "server=.;database=Northwind;integrated security=SSPI" };
强大灵活且易用的语法
//简单查询
var list = Jugg.Select<UserInfo>().Query(); //查询指定的几个字段
list = Jugg.Select<UserInfo>(x => x.Name).Query();
list = Jugg.Select<UserInfo>(x => new { x.Id, x.Name, x.Email }).Query(); //查询的时候,给字段取别名
list = Jugg.Select<UserInfo>(x => new { UserId = x.Id, UserName = x.Name, x.Email }).Query(); //查询的时候取表别名,订单拆表,查询2016年8月份的订单
list = Jugg.Select<Order>().
From("Order_201608").
Where(x => x.Id != null).
OrderBy(x => x.Id).
GetPage(, ).
Query(); //带简单where条件
int idParameter = ;
list = Jugg.Select<UserInfo>().Where(x => x.Id != idParameter).Query(); //强大的查询功能,任意组装where条件
int[] aryId = { , , };
list = Jugg.Select<UserInfo>().
Where(x =>
x.Id != null && // where Id is not null
(x.Age > || x.Email == null) && // and ( Age>18 or Email is null )
x.Id.ToString().Contains("") && // and Id like '%8%'
aryId.Contains(x.Id) && // and Id in (1,2,3)
x.Name.StartsWith("张") && // and Name like '张%'
x.Remark.EndsWith("test") && // and Remark like '%test'
x.Email.Contains("@qq.com") || // and Email like '%@qq.com%'
x.Address != null // or Address is not null
).
Query(); //排序
list = Jugg.Select<UserInfo>().Where(x => x.Id > ).OrderBy(x => x.Id).Query();
list = Jugg.Select<UserInfo>().
Where(x => x.Id > ).
OrderByDesc(x => x.Id).
Query(); //分页查询
list = Jugg.Select<UserInfo>().
Where(x => x.Id != null && (x.Age > || x.Email == null)).
GetPage(). //查询第1页,每页记录数读取JuggConfig.PageRecordCount配置的值
Query();
list = Jugg.Select<UserInfo>().
GetPage(, ). //查询第5页,每页80条记录
Query(); //查询某一个范围的记录
list = Jugg.Select<UserInfo>().
GetRange(, ). //查询第337~437条记录
Query(); //手写sql查询,支持dynamic映射
List<dynamic> listDynamic = Jugg.Select("select * from UserInfo where Id>99;");
list = Jugg.Select<UserInfo>("select * from UserInfo where Id>99;"); listDynamic = Jugg.GetPage("select * from UserInfo where Id>99;");
list = Jugg.GetPage<UserInfo>("select * from UserInfo where Id>99;"); listDynamic = Jugg.GetRange("select * from UserInfo where Id>99;");
list = Jugg.GetRange<UserInfo>("select * from UserInfo where Id>99;"); //单条记录查询
var u = Jugg.Find<UserInfo>(x => x.Id == );
u = Jugg.Single<UserInfo>(x => x.Id == ); //根据条件判断记录是否存在
bool b = Jugg.Exists<UserInfo>(x => x.Id == ); //Max 函数返回一列中的最大值。null 值不包括在计算中。
int uid = Jugg.Max<UserInfo>(x => x.Id).Query<int>(); //Min 函数返回一列中的最小值。null 值不包括在计算中。
uid = Jugg.Min<UserInfo>(x => x.Id).Where(x => x.Id > ).Query<int>(); //Avg 函数返回数值列的平均值。null 值不包括在计算中。
int age = Jugg.Avg<UserInfo>(x => x.Age).Query<int>(); //Sum 函数返回数值列的总数(总额)。
age = Jugg.Sum<UserInfo>(x => x.Age).Query<int>(); //Count(*) 函数返回表中的记录数。
int count = Jugg.Count<UserInfo>().Query<int>(); //Count(column_name) 函数返回指定列的值的数目(null 不计入)。
count = Jugg.Count<UserInfo>(x => x.Name).Query<int>(); //增删改
int id = Jugg.Insert(new UserInfo { Name = "张三" });//根据传入的对象来新增
id = Jugg.Insert<UserInfo>(x => new { x.Name, x.Age }, "李四", );//根据Lambda 表达式,只新增指定的字段 int affectedRowsNum = Jugg.Delete(new UserInfo { Id = });//根据传入对象的Id删除
affectedRowsNum = Jugg.Delete<UserInfo>().Where(x => x.Id == && x.Name != null).Execute();//根据where条件删除
affectedRowsNum = Jugg.Delete<UserInfo>().Execute();//全表删除 affectedRowsNum = Jugg.Update(new UserInfo { Id = , Name = "张三update" });//根据传入的对象来更新 affectedRowsNum = Jugg.Update<UserInfo>(x => new { x.Name }, "张三").
Where(x => x.Id == ).Execute();//根据Lambda 表达式,只更新指定的字段 //通过JuggContext上下文来执行事务
using (JuggContext context = new JuggContext())
{
try
{
context.BeginTransaction(); id = context.Insert<UserInfo>(a => new { a.Name, a.Email, a.Age }, "张三", "123456@qq.com", ); int r1 = context.Update<UserInfo>(x => new { x.Name }, "张三98261571").
Where(x => x.Id == id).
Execute(); int r2 = context.Delete<UserInfo>().
Where(a => a.Id == id).
Execute(); bool r3 = context.Exists<UserInfo>(x => x.Id == id); if (id > && r1 == && r2 == && !r3)
{
context.Commit();
}
else
{
context.Rollback();
}
}
catch
{
context.Rollback();
}
}
其他可选的配置参数
JuggConfig.Debug = true;//开启调试,默认是未开启 //添加类型无效值,用于过滤不必要的字段
JuggConfig.PropertyTypeInvalidValue.Add(typeof(byte), default(byte));
JuggConfig.PropertyTypeInvalidValue.Add(typeof(int), default(int));//public int Age { get; set; },如果属性值为0,则会被Deft自动忽略 JuggConfig.DefaultPrimaryKeyColumnName = "Id";//设置主键名称,默认是 Id JuggConfig.DeftDbConStrKeyName = "DeftDbCon";//配置.config文件中connectionStrings的key,Deft会自动去加载,默认是DeftDbCon //硬编码配置数据库连接对象
JuggConfig.DefaultDbConCfg = new ConnectionStringSettings { ProviderName = "System.Data.SqlClient", ConnectionString = "server=.;database=Northwind;integrated security=SSPI" }; JuggConfig.PageRecordCount = ;//设置分页的每页记录数,默认是50 JuggDbHelper.OnDbExecute += OnDbExecute;//数据库执行事件,必须先通过设置JuggConfig.Debug开启调试模式才会起效果,默认是订阅的 static void OnDbExecute(DbConnection con, string sql, DbParameterCollection dbParameters)
{
//TODO sql日志埋点
string dbParamsStr = null;
foreach (DbParameter item in dbParameters)
{
dbParamsStr += string.Format("{0}:{1} ", item.ParameterName, item.Value);
}
Console.WriteLine(string.Format("{0}{1}{2}{1}", sql, Environment.NewLine, dbParamsStr));
}
性能测试


Deft还有很多不足之处,希望大家多给些意见和需求,cnblogs社区的热度是我强劲的动力。
多表语法的设计和解析早就已经完成了,另外多表mapping还在优化中,暂时没有开放。
关于多表语法设计请前往我的另一篇技术博文:http://www.cnblogs.com/StrangeCity/p/4795117.html谢谢大家的支持,打算自己用,不再放出来了。是否开源纯属个人意愿,无关个体对错,望谅解!
分享自己的超轻量级高性能ORM数据访问框架Deft的更多相关文章
- 超轻量级高性能ORM数据访问组件Deft,比dapper快20%以上
超轻量级高性能ORM数据访问组件Deft,比dapper快20%以上 阅读目录 Deft简介 Deft 核心类介绍 Deft 3分钟即可上手使用 其他可选的配置参数 性能测试 Demo代码下载 回到顶 ...
- 一个类GraphQL的ORM数据访问框架发布
Zongsoft.Data 发布公告 很高兴我们的 ORM 数据访问框架(Zongsoft.Data)在历经两个 SaaS 产品的应用之后,今天正式宣布对外推广! 这是一个类 GraphQL 风格的 ...
- 架构从最简单的数据访问框架(ORM)到资源调度和治理中心(SOA)说起
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 单一应用架构当网站流量很小时,只需一个应用,将 ...
- 9.ORM数据访问
1.Spring对ORM的支持 ORM : 对象关系映射(Object Relational Mapping)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术基于ORM的数据持久层框架有: ...
- 【ASP.NET-中级】SQLHelper数据访问公共类
ASP.NET开发中的三层开发思想指的是UI层(界面显示层),BLL层(业务逻辑层),DAL层(数据访问层)三层,三层之间通过函数的调用来达到降低耦合,易于系统维护的目的,SQLHelper助手类的主 ...
- FluentData,一个轻量级开源的.NET ORM数据持久化框架
FluentData:一种使用Fluent API的新型轻量级ORM模型 FluentData 是微型 ORM(micro-ORM)家族的一名新成员,旨在比大型 ORM(full ORM)更加易用. ...
- ORM数据层框架的设计热点:更新指定的列的几种设计方案
ORM框架的定义:对象-关系映射(Object/Relation Mapping,简称ORM) 常见的是:数据库结构=>映射Object(实体属性)=>基于实体类的操作. 还有一种:数据库 ...
- 【万字长文】Dubbo 入门总结 ,一款高性能的 Java RPC 框架
这篇文章是我学习整理 Dubbo 的一篇文章,首先大部分内容参考了官网 + 某硅谷的视频,内容讲解进行了重新编排,40多张图片,也都是我修改重制的,虽然一万多字,但是其实也可以看出来,更多的内容集中在 ...
- 【转】在Spring中基于JDBC进行数据访问时怎么控制超时
http://www.myexception.cn/database/1651797.html 在Spring中基于JDBC进行数据访问时如何控制超时 超时分类 超时根据作用域可做如下层级划分: Tr ...
随机推荐
- iOS 将一串字符里面的某个字符全部标志出来
NSMutableString * mutStr = [NSMutableString stringWithString:@"aaabbbbaaaccc"]; NSString * ...
- iOS 国际化(本地化)
转自http://www.cocoachina.com/industry/20140526/8554.html 简单说,国际化是一个应用程序国际兼容性设计的过程,比如: 1.以用户母语处理文本输入和输 ...
- 纯手写SpringMVC架构,用注解实现springmvc过程
1.第一步,首先搭建如下架构,其中,annotation中放置自己编写的注解,主要包括service controller qualifier RequestMapping 第二步:完成对应的anno ...
- Ubuntu server12.04安装JDK+Tomcat+mysql
一.安装JDK 1.首先到官网上下载jdk-7u79-linux-x64.tar.gz. 2.将jdk-7u79-linux-x64.tar.gz拷贝到/usr/lib/jdk/目录下面,这里如果没有 ...
- Java提高篇—— 简单介绍Java 的内存泄漏
java最明显的一个优势就是它的内存管理机制.你只需简单创建对象,java的垃圾回收机制负责分配和释放内存.然而情况并不像想像的那么简单,因为在Java应用中经常发生内存泄漏. 本教程演示了什么是内存 ...
- 只有在配置文件或 Page 指令中将 enableSessionState 设置为 true 时,才能使用会话状态。还请确保在应用程序配置的 // 节中包括 System.Web.SessionSta
我直接在父类的构造方法中调用了sessionj结果就报这个错误 搜了好久 让改web.config 可是不起作用 代码如下: public class BasePage:System.Web.UI.P ...
- lkx开发日志1-项目前的准备
遇到的问题 不了解github的使用 不能熟练的用Markdown编辑,比如:放入图片 虚拟机的认知也还是有点模糊 解决的方法 参照老师博文给出的链接,好好学习实操一遍 多请教组员,很多小问题便迎刃而 ...
- Frameset框架优缺点--来自新浪微博
原文地址:http://blog.sina.com.cn/s/blog_4a4b1b010100p6ro.html HTML框架简述 一个浏览器窗体可以通过几个页面的组合来显示.我们可以使用框架来 ...
- 20145320GDB调试汇编堆栈过程分析
GDB调试汇编堆栈过程分析 在这里首先感谢卢肖明的分析博客,为后面的同学减少了很多分析的负担. 分析过程 使用gcc - g example.c -o example -m32指令在64位的机器上产生 ...
- Spring入门
Spring可以做很多事情,它为企业级的开发提供了丰富的功能,但是这些功能的底层实现都依赖于它的两个核心特性, 也就是依赖注入(dependency injection, DI)和面向切面编程(asp ...