目錄
一、ORM簡介
二、ORM的工作原理
三、ORM的優缺點
四、常見的ORM架構
一、ORM簡介
ORM(Object Relational Mapping)對象關係映射,一般指持久化資料和實體物件的映射
資料存放區是絕大多數軟體系統都要接觸到的技術,具有一定規模的軟體產品,為了方便儲存和管理資料,便引入了資料庫這一工具,但是資料如何從程式寫入資料庫的呢?
為方便程式員通過代碼將資料寫入資料庫,一般的語言開發的廠商都會為各種資料庫適配資料庫連接的驅動程式,比如ADO.Net,JDBC等。
但是資料庫連接的驅動程式的職責在於管理串連資料庫,設定串連參數等資訊,通常會返回各自封裝好的資料集類型,驅動程式封裝的類型往往是以資料為核心進行描述的,現代化的軟體設計為了簡便描述事物的特徵都而以物件導向思想為核心,兩者之間的轉換還有很多的路要走。
除卻轉換部分,Sql語句的編寫也是一大學問,一般的程式設計語言都沒有為sql語句定義類型,這是因為每種資料庫的sql語句風格都是不一樣的,難以給出一個統一的方案。退而求其次,一般的程式設計語言都採用字串形式傳遞sql語句到資料庫驅動程式。拋棄各種各樣的sql語句的學習之外,這種方式有一個很大的弊端,那就是sql語句的拼字極容易由於手誤而犯錯。
在這種情境下,ORM架構誕生了!
二、ORM的工作原理
在講解完ORM的前世之後,我們來聊聊ORM架構為我們做了什麼。
在第一節我們提過了,沒有ORM的情況下,主要有兩個槽點:
1.驅動傳回型別和對象不能良好映射
2.SQL語句的學習成本及易錯率(多種資料庫語句難以全部掌握)
那麼,且看我們的ORM如何改善這兩個槽點:
1.資料驅動返回的資料通常都是以資料為核心的資料集合,我們需要通過手動將類對象和資料庫返回的列資料進行一一匹配擷取,然後賦值到對象上。在這裡要感謝泛型和反射兩大文法,通過泛型和反射,我們可以擷取到任何實體類的屬性而不是具體到某一種類型,通過遍曆實體類的屬性去資料集合中一一擷取並複製返回。這一操作便將資料集合的資料完美封裝成了以物件導向為核心的和類相關的對象資料集合。
2.sql語句的拼字,我們可以提供一套公用sql語句模板,然後在具體實體物件操作的時候將實體物件的屬性名稱和屬性值當作參數拼接進去,組裝成完整的sql語句(例如java體系中的Mybatis架構)或者依舊採用封裝一套淺顯易懂的Api,Api內部通過對應方法和實體物件的組裝成sql語句(例如.Net體系中EntityFramework架構)
ORM還為我們做了什嗎?
最重要的兩個問題解決完之後,我們可以在架構中做一些對我們有協助的其他事情。ORM架構做的最多的便是“緩衝”。
作為程式員應該掌握的基礎知識,資料庫操作是要和硬碟打交道的,而程式是在記憶體中啟動並執行,操作記憶體的速度要比操作硬碟快數十倍以上,可見一個訪問量較高的大型系統很容易由於資料庫操作過於頻繁而拖慢整體速度,從而影響系統的使用。因此,ORM架構要協助我們減少資料庫的訪問,加快系統速度。
ORM架構的緩衝系統一般是較為複雜的,而且每種ORM架構對緩衝的實現機制都是不同的。整體的思路卻是一致的,對訪問頻率較高的資料進行緩衝,並在對資料編輯的時候要對緩衝進行更新,以免出現資料不一致的問題。詳細的緩衝實現策略這裡不一一贅述,感興趣可以針對某個ORM架構進行剖析。
三、ORM的優缺點
通過上面兩節的描述,我們很容易總結出ORM架構的優缺點。我們先來說說優點。
ORM架構降低了學習門檻,一個對sql語句並不熟悉的開發人員也可以很容易通過簡易的ORM架構Api進行資料庫的操作。
提高了開發效率,ORM使我們減少很多繁瑣重複的工作量,讓我們的注意力集中在實現業務上。
一定程度上提高了程式的響應速度。
ORM架構的弊端也很明顯,架構會自動產生Sql語句,所有情境的sql語句都是同一套模板,難以自動針對情境對sql語句進行良好的最佳化,某種情境下很容易產生執行很慢的sql語句。如果讓DBA看到這樣的執行sql,必定引來抓狂崩潰。
ORM架構只是為了滿足絕大多數的情境而生的,特殊需要最佳化sql的情境下,我們完全可以直接使用驅動手動執行sql或使用ORM架構內提供的sql語句api進行自訂sql語句。
四、市面常見的ORM架構.Net體系:
EntityFramework,功能強大,lambda api,有些龐大臃腫,很多功能用不上
Dapper,輕量級,資料庫種類支援豐富,sql寫法靈活,運行速度快
CYQ.Data,自動化,日誌,分布式緩衝,弱類型,api簡介
Java體系:
MyBatis,映射採用Xml配置sql,多種映射關係靈活配置,sql需要手動編寫到配置,輕量級,半自動
Hibernate,Xml配置sql,支援HQL語句,移植性好,日誌,重量級,功能全,全自動
Speedment,lambda api,依賴java8