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的開發過程當中也是很是簡單的,您能夠經過如下的方式來參與:

相關文章
相關標籤/搜索