何謂“持久化”
持久(Persistence),即把數(shù)據(jù)(如內(nèi)存中的對象)保存到可永久保存的存儲設備中(如磁盤)。持久化的主要應用是將內(nèi)存中的數(shù)據(jù)存儲在關系型的數(shù)據(jù)庫中,當然也可以存儲在磁盤文件中、XML數(shù)據(jù)文件中等等。
何謂“持久層”
持久層(Persistence Layer),即專注于實現(xiàn)數(shù)據(jù)持久化應用領域的某個特定系統(tǒng)的一個邏輯層面,將數(shù)據(jù)使用者和數(shù)據(jù)實體相關聯(lián)。
何謂“對象數(shù)據(jù)映射(ORM)”
ORM-Object/Relational Mapper,即“對象-關系型數(shù)據(jù)映射組件”。對于O/R,即 Object(對象)和 Relational(關系型數(shù)據(jù)),表示必須同時使用面向?qū)ο蠛完P系型數(shù)據(jù)進行開發(fā)。
備注:建模領域中的 ORM 為 Object/Role Modeling(對象角色建模)。另外這里是“O/R Mapper”而非“O/R Mapping”。相對來講,O/R Mapping 描述的是一種設計思想或者實現(xiàn)機制,而 O/R Mapper指以O/R原理設計的持久化框架(Framework),包括 O/R機制還有 SQL自生成,事務處理,Cache管理等。
除了 ORM 技術,還有以下幾種持久化技術
主動域?qū)ο竽J?br>它是在實現(xiàn)中封裝了關系數(shù)據(jù)模型和數(shù)據(jù)訪問細節(jié)的一種形式。在 J2EE 架構(gòu)中,EJB 組件分為會話 EJB 和實體 EJB。會話 EJB 通常實現(xiàn)業(yè)務邏輯,而實體 EJB 表示業(yè)務實體。實體 EJB 又分為兩種:由 EJB 本身管理持久化,即 BMP(Bean-Managed Persistence);有 EJB 容器管理持久化,即 CMP(Container-Managed Persistence)。BM P就是主動域?qū)ο竽J降囊粋€例子,BMP 表示由實體 EJB 自身管理數(shù)據(jù)訪問細節(jié)。
主動域?qū)ο蟊旧砦挥跇I(yè)務邏輯層,因此采用主動域?qū)ο竽J綍r,整個應用仍然是三層應用結(jié)構(gòu),并沒有從業(yè)務邏輯層分離出獨立的持久化層。
JDO 模式
Java Data Objects(JDO)是 SUN 公司制定的描述對象持久化語義的標準API。嚴格的說,JDO 并不是對象-關系映射接口,因為它支持把對象持久化到任意一種存儲系統(tǒng)中,包括 關系數(shù)據(jù)庫、面向?qū)ο蟮臄?shù)據(jù)庫、基于 XML 的數(shù)據(jù)庫,以及其他專有存儲系統(tǒng)。由于關系數(shù)據(jù)庫是目前最流行的存儲系統(tǒng),許多 JDO 的實現(xiàn)都包含了對象-關系映射服務。
CMP 模式
在 J2EE 架構(gòu)中,CMP(Container-Managed Persistence)表示由 EJB 容器來管理實體 EJB 的持久化,EJB 容器封裝了對象-關系的映射及數(shù)據(jù)訪問細節(jié)。CMP 和 ORM 的相似之處在于,兩者都提供對象-關系映射服務,都把對象持久化的任務從業(yè)務邏輯中分離出來。區(qū)別在于 CMP 負責持久化實體 EJB 組件,而 ORM 負責持久化 POJO,它是普通的基于 Java Bean 形式的實體域?qū)ο蟆?/p>
一般把基于 Java Bean 形式的實體域?qū)ο蠓Q為 POJO(Plain Old Java Object),意為又普通又古老的 Java 對象的意思。隨著各種 ORM 映射工具的日趨成熟和流行,POJO有重現(xiàn)光彩,它和基于 CMP 的實體 EJB 相比,即簡單又具有很高的可移植性,因此聯(lián)合使用 ORM 映射工具和 POJO,已經(jīng)成為一種越來越受歡迎的且用來取代 CMP 的持久化方案。POJO 的缺點就是無法做遠程調(diào)用,不支持分布式計算。
為什么要做持久化和ORM設計
在目前的企業(yè)應用系統(tǒng)設計中,MVC,即 Model(模型)- View(視圖)- Control(控制)為主要的系統(tǒng)架構(gòu)模式。MVC 中的 Model 包含了復雜的業(yè)務邏輯和數(shù)據(jù)邏輯,以及數(shù)據(jù)存取機制(如 JDBC的連接、SQL生成和Statement創(chuàng)建、還有ResultSet結(jié)果集的讀取等)等。將這些復雜的業(yè)務邏輯和數(shù)據(jù)邏輯分離,以將系統(tǒng)的緊耦合關系轉(zhuǎn)化為松耦合關系(即解耦合),是降低系統(tǒng)耦合度迫切要做的,也是持久化要做的工作。MVC 模式實現(xiàn)了架構(gòu)上將表現(xiàn)層(即View)和數(shù)據(jù)處理層(即Model)分離的解耦合,而持久化的設計則實現(xiàn)了數(shù)據(jù)處理層內(nèi)部的業(yè)務邏輯和數(shù)據(jù)邏輯分離的解耦合。而 ORM 作為持久化設計中的最重要也最復雜的技術,也是目前業(yè)界熱點技術。
簡單來說,按通常的系統(tǒng)設計,使用 JDBC 操作數(shù)據(jù)庫,業(yè)務處理邏輯和數(shù)據(jù)存取邏輯是混雜在一起的。
一般基本都是如下幾個步驟:
1、建立數(shù)據(jù)庫連接,獲得 Connection 對象。
2、根據(jù)用戶的輸入組裝查詢 SQL 語句。
3、根據(jù) SQL 語句建立 Statement 對象 或者 PreparedStatement 對象。
4、用 Connection 對象執(zhí)行 SQL語句,獲得結(jié)果集 ResultSet 對象。
5、然后一條一條讀取結(jié)果集 ResultSet 對象中的數(shù)據(jù)。
6、根據(jù)讀取到的數(shù)據(jù),按特定的業(yè)務邏輯進行計算。
7、根據(jù)計算得到的結(jié)果再組裝更新 SQL 語句。
8、再使用 Connection 對象執(zhí)行更新 SQL 語句,以更新數(shù)據(jù)庫中的數(shù)據(jù)。
7、最后依次關閉各個 Statement 對象和 Connection 對象。
由上可看出代碼邏輯非常復雜,這還不包括某條語句執(zhí)行失敗的處理邏輯。其中的業(yè)務處理邏輯和數(shù)據(jù)存取邏輯完全混雜在一塊。而一個完整的系統(tǒng)要包含成千上萬個這樣重復的而又混雜的處理過程,假如要對其中某些業(yè)務邏輯或者一些相關聯(lián)的業(yè)務流程做修改,要改動的代碼量將不可想象。另一方面,假如要換數(shù)據(jù)庫產(chǎn)品或者運行環(huán)境也可能是個不可能完成的任務。而用戶的運行環(huán)境和要求卻千差萬別,我們不可能為每一個用戶每一種運行環(huán)境設計一套一樣的系統(tǒng)。
所以就要將一樣的處理代碼即業(yè)務邏輯和可能不一樣的處理即數(shù)據(jù)存取邏輯分離開來,另一方面,關系型數(shù)據(jù)庫中的數(shù)據(jù)基本都是以一行行的數(shù)據(jù)進行存取的,而程序運行卻是一個個對象進行處理,而目前大部分數(shù)據(jù)庫驅(qū)動技術(如ADO.NET、JDBC、ODBC等等)均是以行集的結(jié)果集一條條進行處理的。所以為解決這一困難,就出現(xiàn) ORM 這一個對象和數(shù)據(jù)之間映射技術。
舉例來說,比如要完成一個購物打折促銷的程序,用 ORM 思想將如下實現(xiàn)(引自《深入淺出Hibernate》):
業(yè)務邏輯如下:
public Double calcAmount(String customerid, double amount)
{
// 根據(jù)客戶ID獲得客戶記錄
Customer customer = CustomerManager.getCustomer(custmerid);
// 根據(jù)客戶等級獲得打折規(guī)則
Promotion promotion = PromotionManager.getPromotion(customer.getLevel());
// 累積客戶總消費額,并保存累計結(jié)果
customer.setSumAmount(customer.getSumAmount().add(amount);
CustomerManager.save(customer);
// 返回打折后的金額
return amount.multiply(protomtion.getRatio());
}
這樣代碼就非常清晰了,而且與數(shù)據(jù)存取邏輯完全分離。設計業(yè)務邏輯代碼的時候完全不需要考慮數(shù)據(jù)庫JDBC的那些千篇一律的操作,而將它交給 CustomerManager 和 PromotionManager 兩個類去完成。這就是一個簡單的 ORM 設計,實際的 ORM 實現(xiàn)框架比這個要復雜的多。
目前有哪些流行的 ORM 產(chǎn)品
目前眾多廠商和開源社區(qū)都提供了持久層框架的實現(xiàn),常見的有
Apache OJB (http://db.apache.org/ojb/)
Cayenne (http://objectstyle.org/cayenne/)
Jaxor (http://jaxor.sourceforge.net)
Hibernate (http://www.hibernate.org)
iBatis (http://www.ibatis.com)
jRelationalFramework (http://ijf.sourceforge.net)
mirage (http://itor.cq2.org/en/oss/mirage/toon)
SMYLE (http://www.drjava.de/smyle)
TopLink (http://otn.oracle.com/products/ias/toplink/index.html)
其中 TopLink 是 Oracle 的商業(yè)產(chǎn)品,其他均為開源項目。
其中 Hibernate 的輕量級 ORM 模型逐步確立了在 Java ORM 架構(gòu)中領導地位,甚至取代復雜而又繁瑣的 EJB 模型而成為事實上的 Java ORM 工業(yè)標準。而且其中的許多設計均被 J2EE 標準組織吸納而成為最新 EJB 3.0 規(guī)范的標準,這也是開源項目影響工業(yè)領域標準的有力見證。