Hibernate4實戰 之第七部分:最佳實務

來源:互聯網
上載者:User
設計細顆粒度的持久類並且使用<component>來實現映射。例如使用一個Address持久類來封裝 street, suburb, state, postcode. 這將有利於代碼重用和簡化代碼重構(refactoring)的工作。 對持久類宣告身份識別符屬性( identifier properties)。Hibernate中標識符屬性是可選的,不過有很多原因來說明你應該使用標識符屬性。我們建議標識符應該是“人造”的(自動產生,不涉及業務含義)。 使用自然鍵(natural keys)標識 對所有的實體都標識出自然鍵,用<natural-id>進行映射。實現equals()和hashCode(),在其中用組成自然鍵的屬性進行比較。 為每個持久類寫一個對應檔 不要把所有的持久類映射都寫到一個大檔案中。把 com.eg.Foo 映射到com/eg/Foo.hbm.xml中, 在團隊開發環境中,這一點顯得特別有意義。 把對應檔作為資源載入 把對應檔和他們的映射類放在一起進行部署。 考慮把查詢字串放在程式外面 如果你的查詢中調用了非ANSI標準的SQL函數,那麼這條實踐經驗對你適用。把查詢字串放在對應檔中可以讓程式具有更好的可移植性。 使用綁定變數 就像在JDBC編程中一樣,應該總是用預留位置"?"來替換非常量值,不要在查詢中用字串值來構造非常量值!更好的辦法是在查詢中使用具名引數。 不要自己來管理JDBC connections Hibernate允許應用程式自己來管理JDBC connections,但是應該作為最後沒有辦法的辦法。如果你不能使用Hibernate內建的connections providers,那麼考慮實現自己來實現org.hibernate.connection.ConnectionProvider 考慮使用使用者自訂類型(custom type) 假設你有一個Java類型,來自某些類庫,需要被持久化,但是該類沒有提供映射操作需要的存取方法。那麼你應該考慮實現org.hibernate.UserType介面。這種辦法使程式碼寫起來更加自如,不再需要考慮類與Hibernate type之間的相互轉換。  在效能瓶頸的地方使用硬式編碼JDBC 在系統中對效能要求很嚴格的一些部分,某些操作也許直接使用JDBC會更好。但是請先確認這的確是一個瓶頸,並且不要想當然認為JDBC一定會更快。如果確實需要直接使用JDBC,那麼最好開啟一個 Hibernate Session 然後從 Session獲得connection,按照這種辦法你仍然可以使用同樣的transaction策略和底層的connection provider。 理解Session清洗( flushing) Session會不時的向資料庫同步持久化狀態,如果這種操作進行的過於頻繁,效能會受到一定的影響。有時候你可以通過禁止自動flushing,盡量最小化非必要的flushing操作,或者更進一步,在一個特定的transaction中改變查詢和其它操作的順序。 在三層結構中,考慮使用託管對象(detached object) 當使用一個servlet / session bean 類型的架構的時候, 你可以把已載入的持久對象在session bean層和servlet / JSP 層之間來回傳遞。使用新的session來為每個請求服務,使用 Session.merge() 或者Session.saveOrUpdate()來與資料庫同步。 在兩層結構中,考慮使用長持久上下文(long persistence contexts).為了得到最佳的延展性,資料庫事務(Database Transaction)應該儘可能的 短。但是,程式常常需要實現長時間啟動並執行“應用程式事務(Application Transaction)”,包含一個從使用者的觀點來看的原子操作。這個應用程式事務 可能跨越多次從使用者請求到得到反饋的迴圈。用脫管對象(與session脫離的對 象)來實現應用程式事務是常見的。或者,尤其在兩層結構中,把Hibernate Session從JDBC串連中脫離開,下次需要用的時候再串連上。絕不要把一個 Session用在多個應用程式事務(Application Transaction)中,否則你的資料 可能會到期失效。 不要把異常看成可恢複的 這一點甚至比“最佳實務”還要重要,這是“必備常識”。當異常發生的時 候,必須要復原 Transaction ,關閉Session。如果你不這樣做的話, Hibernate無法保證記憶體狀態精確的反應持久狀態。尤其不要使用 Session.load()來判斷一個給定標識符的對象執行個體在資料庫中是否存在,應該 使用Session.get()或者進行一次查詢. 對於關聯優先考慮lazy fetching 謹慎的使用主動抓取(eager fetching)。對於關聯來說,若其目標是無法在第二級緩衝中完全緩衝所有執行個體的類,應該使用代理(proxies)與/或具有消極式載入屬性的集合(lazy collections)。若目標是可以被緩衝的,尤其是緩衝的命中率非常高的情況下,應該使用lazy="false",明確的禁止掉eager fetching。如果那些特殊的確實適合使用join fetch 的場合,請在查詢中使用left join fetch。 使用open session in view模式,或者執行嚴格的裝配期(assembly phase)策略來避免再次抓取資料帶來的問題Hibernate讓開發人員們擺脫了繁瑣的Data Transfer Objects (DTO)。在傳統的EJB結構中,DTO有雙重作用:首先,他們解決了entity bean無法序列化的問題;其次,他們隱含地定義了一個裝配期,在此期間,所有在view層需要用到的資料,都被抓取、集中到了DTO中,然後控制才被裝到展示層。Hibernate終結了第一個作用。然而,除非你做好了在整個渲染過程中都維護一個開啟的持久化上下文(session)的準備,你仍然需要一個裝配期(想象一下,你的業務方法與你的展示層有嚴格的契約,資料總是被放置到託管對象中)。這並非是Hibernate的限制!這是實現安全的事務化資料訪問的基本需求。 考慮把Hibernate代碼從商務邏輯代碼中抽象出來 把Hibernate的資料存取程式碼後置到介面(interface)的後面,組合使用DAO和Thread Local Session模式。通過Hibernate的UserType,你甚至可以用硬式編碼JDBC來持久化那些本該被Hibernate持久化的類。 (該建議更適用於規模足夠大應用軟體中,對於那些只有5張表的應用程式並不適合。)不要用怪異的串連映射多對多串連用得好的例子實際上相當少見。大多數時候你在“串連表”中需要儲存額外的資訊。這種情況下,用兩個指向中介類的一對多的串連比較好。實際上,我們認為絕大多數的串連是一對多和多對一的,你應該謹慎使用其它串連風格,用之前問自己一句,是否真的必須這麼做。 偏愛雙向關聯 單向關聯更加難於查詢。在大型應用中,幾乎所有的關聯必須在查詢中可以雙嚮導航。   原創內容 轉自請註明【
http://sishuok.com/forum/blogPost/list/2484.html#7183】 視頻配套PPT,視頻地址【 Hibernate4實戰-獨家視頻課程 】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.