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