DbUtility v3 背后的故事

DbUtility v3 背后的故事

时间

  • DbUtility v3构思了差很少大半年,真正开发到第一个版本发布到NuGet却只花了50天。中途大量时间在完善 Jumony 3,只有三周来开发DbUtility v3,其中总工时大概不超过20个小时。git

  • DbUtility项目开始于2003年,2005年增长了实体转换的支持,2007年由于LINQ的发布,认为这个项目未来不会再有更新,遂开源,也是我开源的第一个项目,当时托管于Codeplex。程序员

  • 每当我要快速搞定一个事情的时候,DbUtility老是最称手的工具,事实上在2007年以后DbUtility有四年没有任何修改,由于我以为没有什么新的功能须要。github

  • 若是不是眼馋.NET Framework 4.5新增的异步支持以及愈来愈多须要定制化查询结果(例如包装成Dictionary)的需求,DbUtility可能到如今都不会重写。数据库

设计

  • DbUtility v3花了很长的时间来构思他的API设计,但愿既能兼容以前的形式,保持简洁,流畅的特色,又利于扩展。下了很大的决心才最终敲定db.T( xxx ).ExecuteXXX()这样的形式,这与以前是不兼容的,因此新发布了一个NuGet包,避免原来的项目升级大面积的编译错误。缓存

  • 利用扩展方法实现的API具备能够自行扩展以及总体切换的特色。这一风格是Jumony独创的,DbUtility把这个手法运用的更为娴熟了。架构

  • 一样花了很长的时间才敲定同时提供T和Template两个如出一辙的方法,事实上T是Template的缩写。虽然具有智能提示能够很是便捷的输入Template,但我仍然认为,T这样的缩写,能够最大限度减小代码的行宽,不带来额外的噪声污染。app

  • db.T( xxx )将不会执行查询,必须使用db.T( xxx ).ExecuteNonQuery()一直是整个设计中的一大痛处,由于可能会忘记写.ExecuteNonQuery。可是的确没有办法解决。框架

  • DbUtility的结果构建器,即ExecuteXXX方法,本来为了简洁是打算去掉Execute前缀的,例如:db.T( “SELECT * FROM Users” ).ExecuteEntities()本来是打算写成db.T( “SELECT * FROM Users” ).Entities()。可是因为考虑到某些查询构建器(即T(xxx))可能难以在一个方法内写完,须要屡次调用构建最终的查询,此时执行查询的方法和构建查询的方法将没有明显的区分,故而依然保留Execute这个前缀。异步

    • 譬如说db.Table( "Users" ).Fields( "*" ).ExecuteEntities<User>()
  • 得益于新的架构设计,Jumony的结果构建器扩展方法写起来很是简单,因此我一口气提供了十几个用于构建不一样类型结果的扩展方法。工具

技术

  • DbUtility拥有理论上性能最好的实体转换器,其原理是根据实体类型直接Emit一个转换器方法出来进行实体转换,而Emit出来的这个方法则巧妙地利用类型字典被缓存。这两项技术都是.NET的不传之秘,较之不使用这两项技术的实现方式性能不在一个数量级。

  • DbUtility的API将C#的泛型和类型推断运用到了极致,事实上诸如T这样的扩展方法,接受的第一个参数的类型是IDbExecutor,而SqlDbUtiltiy类型刚好实现了这个接口,因此能够调用。也就是说若是哪一个数据库的查询器不支持参数化查询(没有实现这个借口),那么就点不出T出来。更神奇的是若是数据库查询器不支持异步查询,那么全部的异步API也会自动消失。

  • DbUtility的异步API实现贯彻了许多能够异步的地方,如打开数据库链接,执行查询。目前只剩下DataReader.Read方法没有调用异步版本,这将在后面的更新中解决。DbUtility恐怕也是第一个实现异步API的数据库访问帮助器。

  • Java移植项目在充分利用C#语法特性上简直使人发指,各类莫名其妙不符合.NET命名规则的API搞得各类乌烟瘴气。而DbUtility不只仅充分利用了泛型、扩展方法一系列特性,更提供了运算符重载,能够很是直观的把参数化查询像拼接字符串同样拼接起来。

  • 在开发DbUtility v3的时候的确考虑过推出一个面向.NET Framework 3.5的版本,可是由于要同时维护两个版本过于费力。且DbUtility并不是个人重心,故而做罢。但事实上删除DbUtility内全部的异步API,即可以获得在3.5下编译经过的代码。

 

优点

不少人会问我,DbUtility的优点在哪里?

事实上我一点儿都不想讨论这个问题,从根本上来讲,DbUtility仅仅只是由于用了太多年很是顺手因此改进了一下让其与时俱进而已。

因为是超轻量级的数据库访问框架,代码量甚至都不过千行,能够说你们都是同样的,半斤八两没有区别。除非哪一个不用Emit来作实体转换(这种垃圾应该赶忙扔掉)会形成性能降低。

可是总的来讲,DbUtility仍然有一些特有的东西是其余轻量级框架难以企及的:

异步数据库查询
DbUtility v3率先推出了异步数据库查询实现,并将在后面不断完善。
可扩展的API
DbUtility v3采用了和Jumony项目同样的可扩展API设计,任何人任何第三方均可以在不修改现有代码之下对现有API进行扩展。
可替换和自定义的API
不只仅是能够扩展示有API,甚至能够把整个API给替换掉。简单来讲,若是你喜欢,甚至能够把DbUtility的API给换成Dapper如出一辙的,但最终仍是以DbUtility的核心在驱动。
参数化查询抽象
在v3的设计中,增长了抽象的参数化查询对象,参数化查询对象是与数据库无关的,在支持参数化查询的数据库,将会尝试采用参数化查询。而在不支持参数化查询的数据库,则尝试将参数值进行相应处理,以免注入式问题。
结构化查询抽象
在未来,DbUtility 还将增长结构化查询抽象,将SQL查询抽象为语法树,经过方法来构建。在执行时再根据实际的数据库转换为相应的语法查询。
查询执行器、查询、结果构建器分离架构
吸收以前的经验,新的架构可使得三部分独立的扩展,和谐的统一。

事实上DbUtility是一个面向真正程序员的超轻量数据访问框架,其拥有极大的可扩展性,而且扩展起来极为简便。这是DbUtility相较于其余超轻量数据访问框架的最大优点。

将来

DbUtility 即将到来的功能包括:

  • 更丰富的配置项
    • 例如不要老是异步打开链接(由于链接池内极可能已经存在链接)
    • 查询超时时间
  • 更好的异步支持(异步的Read调用)
  • 更好的存储过程支持
  • 查询日志记录和查询事件追踪(例如执行了哪些查询,执行了多久)。

在将来的版本中将会添加:

  • 更多的数据库支持(譬如Excel?!)
  • 结构化的 SQL 查询构建工具
  • 自定义类型映射(例如XML字段映射到XDocument)

以及更多,,,,

 

参与

DbUtility是一个开源项目,其足够轻便和简单,因此参与到DbUtility的开发过程当中也是很是简单的,您能够经过如下的方式来参与:

相关文章
相关标签/搜索