如何提升Hibernate4開(kāi)發(fā)能力?
轉(zhuǎn)帖|其它|編輯:郝浩|2012-08-12 21:32:03.000|閱讀
314 次
概述:Hibernate是一個(gè)對(duì)象關(guān)系映射框架,而且還開(kāi)放源碼,同時(shí)對(duì)JDBC進(jìn)行了非常輕量級(jí)的對(duì)象封裝,使得Java程序員可以隨心所欲的使用對(duì)象編程思維來(lái)操縱數(shù)據(jù)庫(kù)。那么你知道如何提升Hibernate4的開(kāi)發(fā)能力嗎?
# 界面/圖表報(bào)表/文檔/IDE等千款熱門(mén)軟控件火熱銷(xiāo)售中 >>
Hibernate是一個(gè)對(duì)象關(guān)系映射框架,而且還開(kāi)放源碼,同時(shí)對(duì)JDBC進(jìn)行了非常輕量級(jí)的對(duì)象封裝,使得Java程序員可以隨心所欲的使用對(duì)象編程思維來(lái)操縱數(shù)據(jù)庫(kù)。那么你知道如何提升Hibernate4的開(kāi)發(fā)能力嗎?
- 為每個(gè)持久類寫(xiě)一個(gè)映射文件,不要把所有的持久類映射都寫(xiě)到一個(gè)大文件中。
- 把映射文件作為資源加載,把映射文件和他們的映射類放在一起進(jìn)行部署。
- 考慮把查詢字符串放在程序外面。把查詢字符串放在映射文件中可以讓程序具有更好的可移植性。
- 設(shè)計(jì)細(xì)顆粒度的持久類并且使用<component>來(lái)實(shí)現(xiàn)映射,這將有利于代碼重用和簡(jiǎn)化代碼重構(gòu)(refactoring)的工作。
- 對(duì)持久類聲明標(biāo)識(shí)符屬性( identifier properties) ,由于Hibernate中標(biāo)識(shí)符屬性是可選的,不過(guò)有很多原因來(lái)說(shuō)明你應(yīng)該使用標(biāo)識(shí)符屬性。
- 使用自然鍵(natural keys)標(biāo)識(shí),對(duì)所有的實(shí)體都標(biāo)識(shí)出自然鍵,用<natural-id>進(jìn)行映射。
- 使用綁定變量,應(yīng)該總是用占位符"?"來(lái)替換非常量值,不要在查詢中用字符串值來(lái)構(gòu)造非常量值!更好的辦法是在查詢中使用命名參數(shù)。不要自己來(lái)管理JDBC connections
Hibernate允許應(yīng)用程序自己來(lái)管理JDBC connections,但是應(yīng)該作為最后沒(méi)有辦法的辦法。
- 考慮使用用戶自定義類型(custom type)
如果有一個(gè)來(lái)自某些類庫(kù)的Java類型,需要被持久化,但是該類沒(méi)有提供映射操作需要的存取方法,那最好是應(yīng)該考慮實(shí)現(xiàn)org.hibernate.UserType接口。這樣使程序代碼寫(xiě)起來(lái)更加自如,不再需要考慮類與Hibernate type之間的相互轉(zhuǎn)換。
- 理解Session清洗( flushing)
Session會(huì)不時(shí)的向數(shù)據(jù)庫(kù)同步持久化狀態(tài),如果這種操作進(jìn)行的過(guò)于頻繁,性能會(huì)受到一定的影響。有時(shí)候可以通過(guò)禁止自動(dòng)flushing,盡量最小化非必要的flushing操作,或者更進(jìn)一步,在一個(gè)特定的transaction中改變查詢和其它操作的順序。
- 在性能瓶頸的地方使用硬編碼的JDBC
在系統(tǒng)中對(duì)性能要求很?chē)?yán)格的一些部分,某些操作也許直接使用JDBC會(huì)更好。但是請(qǐng)先確認(rèn)這的確是一個(gè)瓶頸,并且不要想當(dāng)然認(rèn)為JDBC一定會(huì)更快。如果確實(shí)需要直接使用JDBC,那么最好打開(kāi)一個(gè) Hibernate Session 然后從 Session獲得connection,按照這種辦法仍然可以使用同樣的transaction策略和底層的connection provider。
- 在三層結(jié)構(gòu)中,考慮使用托管對(duì)象(detached object)
當(dāng)使用一個(gè)servlet / session bean 類型的架構(gòu)的時(shí)候,可以把已加載的持久對(duì)象在session bean層和servlet / JSP 層之間來(lái)回傳遞。使用新的session來(lái)為每個(gè)請(qǐng)求服務(wù),使用 Session.merge() 或者Session.saveOrUpdate()來(lái)與數(shù)據(jù)庫(kù)同步。在兩層結(jié)構(gòu)中,考慮使用長(zhǎng)持久上下文(long persistence contexts)。為了得到最佳的可伸縮性,數(shù)據(jù)庫(kù)事務(wù)(Database Transaction)應(yīng)該盡可能的短。但是,程序常常需要實(shí)現(xiàn)長(zhǎng)時(shí)間運(yùn)行的“應(yīng)用程序事務(wù)(ApplicationTransaction)”,包含一個(gè)從用戶的觀點(diǎn)來(lái)看的原子操作。這個(gè)應(yīng)用程序事務(wù)可能跨越多次從用戶請(qǐng)求到得到反饋的循環(huán)。用脫管對(duì)象(與session脫離的對(duì)象)來(lái)實(shí)現(xiàn)應(yīng)用程序事務(wù)是常見(jiàn)的。或者,尤其在兩層結(jié)構(gòu)中,把HibernateSession從JDBC連接中脫離開(kāi),下次需要用的時(shí)候再連接上。絕不要把一個(gè)Session用在多個(gè)應(yīng)用程序事務(wù)(Application Transaction)中,否則你的數(shù)據(jù)可能會(huì)過(guò)期失效。
- 不要把異常看成可恢復(fù)的
這一點(diǎn)甚至比“最佳實(shí)踐”還要重要,這是“必備常識(shí)”。當(dāng)異常發(fā)生的時(shí)候,必須要回滾 Transaction ,關(guān)閉Session。如果不這樣做的話,Hibernate無(wú)法保證內(nèi)存狀態(tài)精確的反應(yīng)持久狀態(tài)。尤其不要使用Session.load()來(lái)判斷一個(gè)給定標(biāo)識(shí)符的對(duì)象實(shí)例在數(shù)據(jù)庫(kù)中是否存在,應(yīng)該使用Session.get()或者進(jìn)行一次查詢。
- 對(duì)于關(guān)聯(lián)優(yōu)先考慮lazy fetching
謹(jǐn)慎的使用主動(dòng)抓取(eager fetching)。對(duì)于關(guān)聯(lián)來(lái)說(shuō),若其目標(biāo)是無(wú)法在第二級(jí)緩存中完全緩存所有實(shí)例的類,應(yīng)該使用代理(proxies)與/或具有延遲加載屬性的集合(lazy collections)。若目標(biāo)是可以被緩存的,尤其是緩存的命中率非常高的情況下,應(yīng)該使用lazy="false",明確的禁止掉eager fetching。如果那些特殊的確實(shí)適合使用join fetch 的場(chǎng)合,請(qǐng)?jiān)诓樵冎惺褂胠eft join fetch。
- 使用open session in view模式,或者執(zhí)行嚴(yán)格的裝配期(assembly phase)策略,避免再次抓取數(shù)據(jù)帶來(lái)的問(wèn)題
Hibernate讓開(kāi)發(fā)者們擺脫了繁瑣的Data Transfer Objects (DTO)。在傳統(tǒng)的EJB結(jié)構(gòu)中,DTO有雙重作用:首先,他們解決了entity bean無(wú)法序列化的問(wèn)題;其次,他們隱含地定義了一個(gè)裝配期,在此期間,所有在view層需要用到的數(shù)據(jù),都被抓取、集中到了DTO中,然后控制才被裝到表示層。Hibernate終結(jié)了第一個(gè)作用。然而,除非你做好了在整個(gè)渲染過(guò)程中都維護(hù)一個(gè)打開(kāi)的持久化上下文(session)的準(zhǔn)備,你仍然需要一個(gè)裝配期(想象一下,你的業(yè)務(wù)方法與你的表示層有嚴(yán)格的契約,數(shù)據(jù)總是被放置到托管對(duì)象中)。這并非是Hibernate的限制!這是實(shí)現(xiàn)安全的事務(wù)化數(shù)據(jù)訪問(wèn)的基本需求。
- 考慮把Hibernate代碼從業(yè)務(wù)邏輯代碼中抽象出來(lái)
把Hibernate的數(shù)據(jù)存取代碼隱藏到接口(interface)的后面,組合使用DAO和Thread Local Session模式。通過(guò)Hibernate的UserType,你甚至可以用硬編碼的JDBC來(lái)持久化那些本該被Hibernate持久化的類。 (該建議更適用于規(guī)模足夠大應(yīng)用軟件中,對(duì)于那些只有5張表的應(yīng)用程序并不適合。)不要用怪異的連接映射多對(duì)多連接用得好的例子實(shí)際上相當(dāng)少見(jiàn)。大多數(shù)時(shí)候你在“連接表”中需要保存額外的信息。這種情況下,用兩個(gè)指向中介類的一對(duì)多的連接比較好。實(shí)際上,我們認(rèn)為絕大多數(shù)的連接是一對(duì)多和多對(duì)一的,你應(yīng)該謹(jǐn)慎使用其它連接風(fēng)格,用之前問(wèn)自己一句,是否真的必須這么做。
- 偏愛(ài)雙向關(guān)聯(lián)
單向關(guān)聯(lián)更加難于查詢。在大型應(yīng)用中,幾乎所有的關(guān)聯(lián)必須在查詢中可以雙向?qū)Ш健?/li>
標(biāo)簽:
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:網(wǎng)絡(luò)