秦亞莉 秦 國 侯國照
摘要:文章在面向?qū)ο蟪绦蛟O(shè)計中的數(shù)據(jù)持久化問題的背景下,分析了Hibernate的結(jié)構(gòu)及運(yùn)行機(jī)理,并將其與CMP做了對比,然后根據(jù)實(shí)際項(xiàng)目經(jīng)驗(yàn)總結(jié)出實(shí)際開發(fā)中的一些實(shí)踐準(zhǔn)則,使初級開發(fā)者可以能夠盡快地把握Hibernate的應(yīng)用技巧,充分利用Hibernate的優(yōu)點(diǎn),提高開發(fā)效率,增強(qiáng)系統(tǒng)的穩(wěn)定性、可移植性。
關(guān)鍵字:面向?qū)ο?;Hibernate;持久層;最佳實(shí)踐
中圖分類號:TP312文獻(xiàn)標(biāo)識碼:A文章編號:1009-2374(2009)02-0074-02
OOP即面向?qū)ο蟮某绦蛟O(shè)計(Object-Oriented Programming),是目前占據(jù)主流地位的一種程序設(shè)計思想。在軟件工程的各個階段運(yùn)用并體現(xiàn)面向?qū)ο蟮乃枷耄呀?jīng)成為軟件分析、設(shè)計、開發(fā)的基本方法。但對象只能存在于內(nèi)存中,而內(nèi)存不能永久保存數(shù)據(jù)。如果要永遠(yuǎn)保存對象的狀態(tài),需要進(jìn)行對象的持久化,即把對象存儲到專門的數(shù)據(jù)存儲中。
關(guān)系數(shù)據(jù)庫是目前數(shù)據(jù)持久化存儲的主要形式。關(guān)系數(shù)據(jù)庫系統(tǒng)中存放的是關(guān)系數(shù)據(jù),是非面向?qū)ο蟮?,其操作的特點(diǎn)是“集合性”的,因而關(guān)系數(shù)據(jù)本身是無法表現(xiàn)出對象之間存在的關(guān)聯(lián)和繼承關(guān)系。
于是,在面向?qū)ο蟮能浖O(shè)計中使用關(guān)系數(shù)據(jù)庫做為數(shù)據(jù)的持久化方式,就必然需要進(jìn)行對象-關(guān)系的映射(Object/Relation Mapping,簡稱ORM)。那么,如何能夠以較低的代價在對象和關(guān)系模型之間相互轉(zhuǎn)化,提高系統(tǒng)的開發(fā)效率就成了一個非常重要的問題。幸運(yùn)的是ORM框架——Hibernate為人們解決了這一問題。越來越多的Java開發(fā)人員把Hibernate作為企業(yè)應(yīng)用和關(guān)系數(shù)據(jù)庫之間的中間件。使用Hibernate,開發(fā)者可以采用面向?qū)ο蟮姆椒ú僮鲾?shù)據(jù)庫,提高工作效率[1]。
一、Hibernate
Hibernate是一個開放源代碼的對象關(guān)系映射框架,它對JDBC進(jìn)行了輕量級的對象封裝,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數(shù)據(jù)庫。Hibernate可以應(yīng)用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應(yīng)用中使用,最具革命意義的是,Hibernate可以在應(yīng)用EJB的J2EE架構(gòu)中取代CMP[2],完成數(shù)據(jù)持久化的重任。
(一)Hibernate體系結(jié)構(gòu)
Hibernate體系結(jié)構(gòu)如圖一所示??梢钥闯觯琀ibernate是Java應(yīng)用和關(guān)系數(shù)據(jù)庫之間的橋梁,它將應(yīng)用層對對象的操作通過XMLMapping轉(zhuǎn)化為針對關(guān)系數(shù)據(jù)庫特定操作,使程序員專注于業(yè)務(wù)邏輯的開發(fā),而不用關(guān)心數(shù)據(jù)庫的操作問題。Hibernate以hibernate.properties或hibernate.cfg.xml作為系統(tǒng)配置文件,并通過類映射文件(*.hbm.xml)將實(shí)體類映射到數(shù)據(jù)庫中的表,為應(yīng)用程序提供持久化服務(wù)[3]。
(二)Hibernate的核心接口
Hibernate的核心接口一共有5個,分別為:Session、SessionFactory、Transaction、Query和Configuration。這5個核心接口在任何開發(fā)中都會用到。下面對這五的核心接口分別加以介紹。
Session接口負(fù)責(zé)執(zhí)行被持久化對象的CRUD(Create,Retrieve,Update,Delete)操作。但需要注意的是Session對象是非線程安全的。
SessionFactroy接口負(fù)責(zé)初始化Hibernate。它充當(dāng)數(shù)據(jù)存儲源的代理,并負(fù)責(zé)創(chuàng)建Session對象。需要注意的是SessionFactory并不是輕量級的,一般情況下,一個項(xiàng)目通常只需要一個SessionFactory就夠,當(dāng)需要操作多個數(shù)據(jù)庫時,可以為每個數(shù)據(jù)庫指定一個SessionFactory。
Configuration接口負(fù)責(zé)配置并啟動Hibernate,創(chuàng)建SessionFactory對象。在Hibernate的啟動的過程中,Configuration類的實(shí)例首先定位映射文檔位置、讀取配置,然后創(chuàng)建SessionFactory對象。
Transaction接口負(fù)責(zé)事務(wù)相關(guān)的操作。它是可選的,開發(fā)人員也可以設(shè)計編寫自己的底層事務(wù)處理代碼。
Query和Criteria接口負(fù)責(zé)執(zhí)行各種數(shù)據(jù)庫查詢。它可以使用HQL語言或SQL語句兩種表達(dá)方式。
二、Hibernate與CMP的對比
J2EE的標(biāo)準(zhǔn)是CMP Entity Bean,而實(shí)際應(yīng)用中受到詬病最多的也是它。Hibernate至少比CMP2.0有以下優(yōu)點(diǎn):
1.兼容性。EJB的規(guī)范是固定的,但是各個軟件廠商的實(shí)現(xiàn)卻是各不相同的,這樣就造成學(xué)習(xí)了廠商A的EJB使用后,在使用廠商B的EJB組件時又要重新學(xué)習(xí)相關(guān)的使用手冊,這樣就勢必造成資源的浪費(fèi)。
2.性能。Hibernate的操作是本地調(diào)用,CMP2.0雖然也有Local接口,但是Web層還是需要通過Remote接口訪問EJB層的數(shù)據(jù)。那么序列化、網(wǎng)絡(luò)調(diào)用等過程必將造成性能的下降。
3.動態(tài)Query。Entity Bean很難實(shí)現(xiàn)動態(tài)Query,這是因?yàn)樗诖a自動生成技術(shù),即最終的執(zhí)行代碼是在部署編譯時生成的。而Hibernate則有根本的改變,它基于reflection機(jī)制,運(yùn)行時動態(tài)Query是很自然的事。另外,Hibernate幾乎支持所有的SQL語法,傳統(tǒng)數(shù)據(jù)庫可以做的它就可以做。
4.發(fā)展速度。EJB是許多大的軟件公司共同協(xié)商、制定的一套標(biāo)準(zhǔn),其更新改進(jìn)的速度遠(yuǎn)遠(yuǎn)無法與Hibernate相比。Hibernate的核心程序員只有一人,而且以開源的方式在全世界這個范圍內(nèi)發(fā)布,在大量的開發(fā)人員努力下不斷地改進(jìn),它改進(jìn)的速度是EJB無法相比的。
三、最佳實(shí)踐
Hibernate是一個非常優(yōu)秀的ORM框架,但這并不意味著它是萬能的、自動的,就像好車還得要技術(shù)高超的司機(jī)來駕駛才能發(fā)揮出應(yīng)有的性能一樣。在實(shí)際使用中,用戶需要深入了解應(yīng)用的需求,并結(jié)合Hibernate的自身特點(diǎn)來進(jìn)行準(zhǔn)確而有效的設(shè)計。通過對許多項(xiàng)目的分析,筆者總結(jié)出一些實(shí)踐準(zhǔn)則如下:
1.設(shè)計細(xì)顆粒度的持久類并且使用
2.對持久類聲明標(biāo)識符屬性(identifier properties),標(biāo)識符應(yīng)該是自動生成、不涉及業(yè)務(wù)含義。
3.對所有的實(shí)體都標(biāo)識出自然鍵,用
4.考慮把查詢字符串放在程序外面,讓程序具有更好的可移植性。
5.在查詢中使用命名參數(shù)。
6.不要自己來管理JDBC connections。
7.考慮使用用戶自定義類型(custom type)。
8.在性能瓶頸的地方使用硬編碼的JDBC,但一定要確認(rèn)這些操作直接使用JDBC會更好。
9.理解Session清洗(flushing),避免過于頻繁flushing。
10.對于關(guān)聯(lián)優(yōu)先考慮lazy fetching,但要注意緩存限制。
11.考慮把Hibernate代碼從業(yè)務(wù)邏輯代碼中抽象出來。
12.不要用怪異的連接映射,偏愛雙向關(guān)聯(lián),在大型應(yīng)用中,幾乎所有的關(guān)聯(lián)必須在查詢中可以雙向?qū)Ш健?/p>
13.關(guān)于Map文件的生成,既可以在數(shù)據(jù)庫設(shè)計完成后使用工具一次性的生成Mapping文件,也可以在軟件的編碼中嵌入數(shù)據(jù)說明,然后使用XDoclet[4]來自動生成Mapping文件。
四、結(jié)語
雖然Hibernate有這諸多的優(yōu)點(diǎn),但目前來看Hibernate也存在著缺點(diǎn),比如:Hibernate提供了自動生成mapping文件的工具,但還需根據(jù)具體應(yīng)用做必要的手工調(diào)整。總之,Hibernate雖然是一個優(yōu)秀的工具,但是其效能的發(fā)揮是以開發(fā)人員對系統(tǒng)的理解為基礎(chǔ)的,只有合理設(shè)計關(guān)系數(shù)據(jù)庫,并根據(jù)應(yīng)用中不同的性能需求做相應(yīng)的設(shè)計,才能充分地發(fā)揮Hibernate的優(yōu)點(diǎn),簡化持久層開發(fā),提高系統(tǒng)的開發(fā)效率。
參考文獻(xiàn)
[1]孫衛(wèi)琴.精通Hibernate:Java對象持久化技術(shù)詳解[M].北京:電子工業(yè)出版社,2005.
[2]楊紹方.深入掌握J(rèn)2EE編程技術(shù)[M].科學(xué)出版社,2002.
[3]蔡雪燾.Hibernate開發(fā)及整合應(yīng)用大全[M].北京:清華大學(xué)出版社,2006.
[4](德)Christian Bauer,(澳)Gavin King 著,楊春花,彭永康,俞黎敏譯.Hibernate實(shí)戰(zhàn)(第2版)[M].北京:人民郵電出版社,2008.