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