Hibernate 性能優化法則

Hibernate 是 Java EE 應用中流行的 JPA 框架,簡單易用,但很多使用過 Hibernate 的開發者都普遍反映 Hibernate 性能低下。究其原因,還是使用者沒有對 Hibernate 進行過深入理解,對 Hibernate 的應用也只是浮于表面。本文介紹了幾種簡單實現 Hibernate 性能優化的方法。

啟用 Hibernate 數據統計策略

沒有測量就沒有優化。啟用 Hibernate 數據統計策略,用來做優化前后的數據對比。

將 hibernate.generate_statistics 置為 true ,日志級別 org.hibernate.stat 置為 DEBUG ,Hibernate 會收集內部統計數據,比如查詢的性能、緩存命中情況等。

做到這一步,你可以避免常見的問題,比如,查詢緩慢,查詢次數太多,緩存沒有使用等情況。還有一點要注意,數據庫的測試數據量大小對于查詢結果影響也很大。

改進慢查詢

慢查詢并不是一個真正的 JPA 或 Hibernate 的問題。這種性能問題在每一個框架中都有可能發生,甚至是普通的 SQL 或者 JDBC,這時就需要在固定的 SQL 和數據庫級別進行分析。如果你選擇這樣做了,那你就不能用 JPQL 或 Criteria API 來處理復雜或優化 SQL 查詢。在這種情況下,需要使用本機查詢來執行本地的SQL語句,在其中您可以使用所有 SQL 和專有的數據庫功能。但是,這也有一個缺點。你得到是一個 Object[],而不是你從 JPQL 獲得強類型的結果。您可以通過編程方式或通過 @SqlResultSetMapping 注解映射到 Object[] 。

選擇正確的 FetchType

使用錯誤的 FetchType 可能會導致在執行加載所需的實體時,查詢數量巨大。

  • FetchType.LAZY:懶加載,加載一個實體時,定義懶加載的屬性不會馬上從數據庫中加載。
  • FetchType.EAGER:急加載,加載一個實體時,定義急加載的屬性會立即從數據庫中加載。

比方 User 類有兩個屬性,name 跟 address,就像一般的系統,登錄后用戶名是需要在右上角顯示出來的,此屬性用到的幾率極大,要馬上到數據庫查,用急加載;而用戶地址大多數情況下不需要顯示出來,只有在查看用戶資料是才需要顯示,需要用了才查數據庫,用懶加載就好了。

所以,要正確的使用 FetchType。

使用特定的查詢語句

當真正需要急加載時,可以使用特定的查詢語句,比如用 FETCH JOIN 代替  JOIN 。 FETCH 會告訴 Hibernate 不單單是查詢兩個實體,還要把實體相關的實體從數據庫查出來。

重量級操作交給數據庫處理

Java 的處理邏輯能力并不一定比數據庫本身的處理能力強,所以有些大數據集操作可以交給數據庫處理。

使用緩存

在相同數據經常被讀取的情況下,使用緩存來提高查詢效率。

Hibernate 提供了三種緩存方式來組合使用。

  • 1st level cache(一級緩存):默認情況下是激活的,用來緩存在當前會話中使用的所有實體。
  • 2nd level cache(二級緩存):也可以存儲實體,需要通過在 persistence.xml 設置 shared-cache-mode 屬性。特定實體的高速緩存可以通過在實體上添加 javax.persistence.Cacheable  或 org.hibernate.annotations.Cache  注解來實現。
  • query cache(查詢緩存):不存儲實體。它緩存查詢結果,并且只包含實體引用和標量值。你需要通過在 persistence.xml 文件中設置 hibernate.cache.use_query_cache  屬性和 Query 的  cacheable  屬性來激活該緩存。

在更新和刪除時使用批量處理

JPA 2.1 新增了 CriteriaUpdate 和  CriteriaDelete 接口。

  • CriteriaUpdate 接口定義用于使用 Criteria API 批量更新的操作功能。該批量更新操作直接映射到數據庫的更新操作,會繞過任何樂觀鎖檢查。
  • CriteriaDelete 接口定義用于使用 Criteria API 批量刪除的操作功能。該批量刪除操作直接映射到數據庫的刪除操作。持久化上下文不會同步批量刪除的結果。

參考引用

 

來自:http://www.importnew.com/21532.html

 

 本文由用戶 deuc0344 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!