DbUtility v3

历史

七年前,也就是2007年,我在博客园写了一篇博文,开源并发布了恐怕是我第一个开源项目,DbUtility。其设计的初衷就是为了简化ADO.NET繁琐的数据库访问过程,提供极为简洁流畅的语法访问数据库,像这样:

dbUtility.ExecuteSingleRow("SELECT username, userdata FROM Users WHERE ID = {0}", userId );

这一行代码将自动创建和打开数据库链接、创建命令对象、包装参数、执行查询并将结果包装成DataRow返回。

时过境迁,七年后的现在,我们有了非常多的重量级的ORM如NHibernate、EntityFramework,和各种快速访问数据库的框架。但有些时候,我们仍然会希望,执行一个简单的SQL查询,并获得其结果。

这时候我经常会想起DbUtility这个家伙,所以在七年后的今天,我把DbUtility的所有代码重新写了一次,推出了这个超轻量级数据库访问帮助器的最新版本,DbUtility v3,目前在GitHub上开源

简单查询

如果你从来没有听说过这个东西,也没有关系,DbUtility是被设计为超轻量级(无需任何额外的配置,不会产生任何未知的行为),随手可用(语法简单、直接、明了)的数据库访问帮助器。

一个典型的DbUtility v3的代码像是下面这样:

db.T( "SELECT Username FROM Users WHERE ID = {0};", userId ).ExecuteScalar<string>();

几乎每个数据库的查询差不多都是这种形式,其中可以分为三个部分:

查询执行器,即上面代码中的 db ,这个东西负责执行查询,其与数据库直接相关,一般我们可以使用一个连接字符串配置或者连接字符串来创建查询执行器的实例:

var db = new SqlDbUtility( "数据库连接字符串" );

var db = SqlDbUtility.Create( "连接字符串名称" );

紧跟着查询执行器的部分是查询构建器,这一部分决定了数据库具体要执行的查询。也就是上面代码中的 .T( "SELECT Username FROM Users WHERE ID = {0};", userId ) 部分,T的意思是Template,即模板,这也是DbUtility最基本的查询构建方式,通过SQL指令模板来构建。我们可以使用类似于string.Format的语法指定字符串模板和模板参数。但与直接调用string.Format不同的是,这个模板中的参数会被转换为参数化查询中的参数,从而没有注入式漏洞的隐患。即上述的查询模板最终转换成的SQL大体上是这样的:

DECLARE @Param0 AS int = userId-value;
SELECT Username FROM Users WHERE ID =@Param0;

T或者Template方法(事实上T是缩写)会解析查询模板并创建一个抽象的参数化查询对象,参数化查询对象会根据具体的数据库产生相应的参数化查询进行执行。

最后的一部分是结果构建器,也就是上面代码中的 .ExecuteScalar<string>() ,ExecuteScalar即是取出查询结果中的第一行第一列。

DbUtility v3提供了极为丰富的结果构建器,除了ExecuteScalar、ExecuteNonQuery、ExecuteDataTable、ExecuteFirstRow这些常见常用的之外,还有自动将结果包装成实体的ExecuteEntity和ExecuteEntities,包装成动态对象的ExecuteDynamicObject和ExecuteDynamics等等等等。丰富的结果构建器可以极大地简化你访问数据库的代码。

不过最重要的是,DbUtility v3设计了一个便于扩展的架构,所有的查询构建器、结果构建器,全部可以简单地自定义扩展,或者说事实上整个DbUtility提供的所有的查询构建器和查询结果构建器本来就是用扩展方法扩展出来的。

进阶

如果你要开启数据库事务,使用DbUtility也非常的方便:

using( var transaction = db.BeginTransaction() )
{
transaction.T( "SELECT Username FROM Users WHERE ID = {0}", userId ).ExecuteScalar<string>();//事务对象可以直接当做查询执行器来使用。 //... transaction.Commit();//提交事务,若在离开using块之前没有提交事务,则事务会自动回滚。
}

异步查询数据库也非常的简单:

var username = await db.T("SELECT Username FROM Users WHERE ID = {0};", userId ).ExecuteScalarAsync<string>();//加上Async后缀即是访问异步版本。

Jumony的示例项目全部数据库访问改用DbUtility后,比起EntityFramework来说,不仅配置消失了,性能也更好了(因为DbUtility是超轻量级的),更重要的是,结合MVC 4的异步Action,我们可以非常简单的在ASP.NET中异步访问数据库以获得更大的吞吐量:

public async Task<ActionResult> Index()
{
return View( "index", await dbUtility.T( "SELECT ID, Title, Completed FROM Tasks" ).ExecuteEntitiesAsync<TodoTask>() );
}

尾声

在马上发布的更新中,我们可以简单地把多个参数化查询对象像拼接字符串一样拼接起来:

var query = db.T( "SELECT * FROM Users" );

query += "WHERE" + Db.Join( "AND", Db.T( "Age > {0}", age ), Db.T( "FirstName LIKE '%'+{0}+'%'", name ) );

var result = query.ExecuteEntities<User>();

在未来的版本中,将支持更多的数据库类型(如Excel),更好的查询构建(值得期待的超轻量SQL语法: db.Q( "users.username ?users.userId = @0", userId ) )。

DbUtility v3现在已经可以通过 NuGet 获取。

全线开源项目全部在GitHub以Apache协议开源,DbUtility:超轻量数据访问帮助,Jumony:真正的HTML分析、处理、绑定、视图引擎,WebTest:在ASP.NET环境直接进行单元测试,LogUtility:文本日志记录利器。

以上项目均可以在 NuGet 下载。

DbUtility v3的更多相关文章

  1. DbUtility v3 背后的故事

    DbUtility v3 背后的故事 时间 DbUtility v3构思了差不多大半年,真正开发到第一个版本发布到NuGet却只花了50天.中途大量时间在完善 Jumony 3,只有三周来开发DbUt ...

  2. 扩展 DbUtility (1)

    本文原始路径: https://www.zybuluo.com/Ivony/note/14074 前言 DbUtility v3 是一个开源的轻量级数据库访问框架,源代码通过 Apache 协议发布, ...

  3. DbUtility Ex

    扩展 DbUtility (1) 2014-05-22 21:48 by Ivony..., 234 阅读, 3 评论, 收藏, 编辑 本文原始路径: https://www.zybuluo.com/ ...

  4. DBImport V3.7版本发布及软件稳定性(自动退出问题)解决过程分享

    DBImport V3.7介绍: 1:先上图,再介绍亮点功能: 主要的升级功能为: 1:增加(Truncate Table)清表再插入功能: 清掉再插,可以保证两个库的数据一致,自己很喜欢这个功能. ...

  5. AEAI DP V3.6.0 升级说明,开源综合应用开发平台

    AEAI DP综合应用开发平台是一款扩展开发工具,专门用于开发MIS类的Java Web应用,本次发版的AEAI DP_v3.6.0版本为AEAI DP _v3.5.0版本的升级版本,该产品现已开源并 ...

  6. atitit 商业项目常用模块技术知识点 v3 qc29

    atitit 商业项目常用模块技术知识点 v3 qc29 条码二维码barcodebarcode 条码二维码qrcodeqrcode 条码二维码dm码生成与识别 条码二维码pdf147码 条码二维码z ...

  7. Atitit. 提升存储过程与编程语言的可读性解决方案v3 qc25.docx

    Atitit. 提升存储过程与编程语言的可读性解决方案v3 qc25.docx 1. 大原则:分解+命名1 1.1. 命名规范1 1.2. 分层.DI和AOP是继OO1 1.3. 运算符可读性一般要比 ...

  8. 高效 Java Web 开发框架 JessMA v3.5.1

    JessMA 是功能完备的高性能 Full-Stack Web 应用开发框架,内置可扩展的 MVC Web 基础架构和 DAO 数据库访问组件(内部已提供了 Hibernate.MyBatis 与 J ...

  9. 高性能 TCP & UDP 通信框架 HP-Socket v3.5.3

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...

随机推荐

  1. Apache日志按天切割

    Linux系统配置方法: 将其改为 ErrorLog "| /usr/local/apache/bin/rotatelogs /home/logs/www/error_%Y%m%d.log ...

  2. android 动画效果

    动画资源 一.分类: (一).概要:         3.0以前,android支持两种动画模式,补间动画(tween animation),帧动画(frame animation),在android ...

  3. 源代码管理工具之SVN

    源代码管理工具SVN是一款非常强大的源代码管理工具,现在国内70%-90%的公司都在使用SVN来管理源代码,下面就让小编给大家着重介绍一下SVN的使用,SVN的使用主要分为下面几块. SVN的使用环境 ...

  4. [原创]python之socket-ftp

    今天来讲讲ftp文件下载,感觉挺有趣的,知道吧,就那种看到新文件生成,而自己写的代码也不多,那种成就感! 一.需求: 客户端发送指令给服务端,服务端根据指令找到相应文件,发送给客户端 分析: PS:e ...

  5. 【转】Jsduck一个纯净的前端文档生成神器

    让前端程序更具可维护性,是一个老生常谈的问题,大多数时候我们都关注于应用层面的代码可维护性,如:OO.模块化.MVC,编码规范.可扩展和复用性,但这都是属于设计层面需要考虑的事情,可维护性还应包含另一 ...

  6. web.xml 中的listener、 filter、servlet 加载顺序及其详解

    在项目中总会遇到一些关于加载的优先级问题,近期也同样遇到过类似的,所以自己查找资料总结了下,下面有些是转载其他人的,毕竟人家写的不错,自己也就不重复造轮子了,只是略加点了自己的修饰. 首先可以肯定的是 ...

  7. Linux SendMail发送邮件失败诊断案例(二)

    Linux上Sendmail经常由于一些配置问题,导致邮件发送失败,下面整理.收集了一些邮件发送失败.异常的案例. 案例1:在新服务器上测试sendmail发送邮件时,发现邮件发送不成功,检查/var ...

  8. 【转】深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接

    [原文]:http://www.jb51.net/article/39432.htm 1.内联接(典型的联接运算,使用像 =  或 <> 之类的比较运算符).包括相等联接和自然联接.    ...

  9. shell实现ping命令查看哪些主机在线

    #!/bin/bash .{..};do -i 0.5 $a >/dev/null && echo "$a 在线" || echo "$a 离线&q ...

  10. Maven 的classifier的作用

    直接看一个例子,maven中要引入json包,于是使用了 <dependency> <groupId>net.sf.json-lib</groupId> <a ...