Hibernate 性能優化法則

原文同步至:http://waylau.com/tips-to-boost-your-hibernate-performance/html


Hibernate 是 Java EE 應用中流行的 JPA 框架,簡單易用,但不少使用過 Hibernate 的開發者都廣泛反映 Hibernate 性能低下。究其緣由,仍是使用者沒有對 Hibernate 進行過深刻理解,對 Hibernate 的應用也只是浮於表面。本文介紹了幾種簡單實現 Hibernate 性能優化的方法。java

啓用 Hibernate 數據統計策略

沒有測量就沒有優化。啓用 Hibernate 數據統計策略,用來作優化先後的數據對比。數據庫

hibernate.generate_statistics置爲true,日誌級別org.hibernate.stat置爲DEBUG,Hibernate 會收集內部統計數據,好比查詢的性能、緩存命中狀況等。編程

作到這一步,你能夠避免常見的問題,好比,查詢緩慢,查詢次數太多,緩存沒有使用等狀況。還有一點要注意,數據庫的測試數據量大小對於查詢結果影響也很大。api

改進慢查詢

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

選擇正確的 FetchType

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

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

比方 User 類有兩個屬性,name 跟 address,就像通常的系統,登陸後用戶名是須要在右上角顯示出來的,此屬性用到的概率極大,要立刻到數據庫查,用急加載;而用戶地址大多數狀況下不須要顯示出來,只有在查看用戶資料是才須要顯示,須要用了才查數據庫,用懶加載就行了。oracle

因此,要正確的使用 FetchType。app

使用特定的查詢語句

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

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

Java 的處理邏輯能力並不必定比數據庫自己的處理能力強,因此有些大數據集操做能夠交給數據庫處理。

使用緩存

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

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

  • 1st level cache(一級緩存):默認狀況下是激活的,用來緩存在當前會話中使用的全部實體。
  • 2nd level cache(二級緩存):也能夠存儲實體,須要經過在 persistence.xml 設置shared-cache-mode屬性。特定實體的高速緩存能夠經過在實體上添加javax.persistence.Cacheableorg.hibernate.annotations.Cache 註解來實現。
  • query cache(查詢緩存):不存儲實體。它緩存查詢結果,而且只包含實體引用和標量值。你須要經過在 persistence.xml 文件中設置hibernate.cache.use_query_cache 屬性和 Query 的 cacheable 屬性來激活該緩存。

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

JPA 2.1 新增了 CriteriaUpdateCriteriaDelete 接口。

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

參考引用

相關文章
相關標籤/搜索