Hibernate性能優化

jopen 11年前發布 | 19K 次閱讀 Hibernate 持久層框架

性能優化是一個很大的話題,大到程序架構優化,數據庫設計等,小到一個特定算法,甚至js優化等等。這里我們只簡單談一下hibernate的性能優化。

在使用Hibernate的時候,通過正確的方法和策略,可以提高執行效率。

 

(一)抓取策略

抓取策略(fetching strategy)是指:當應用程序需要在(Hibernate實體對象圖的)關聯關系間進行導航的時候, Hibernate如何獲取關聯對象的策略。抓取策略可以在O/R映射的元數據中聲明,也可以在特定的HQL 或條件查詢(Criteria Query)中重載聲明。

 

例如單端代理,集合代理,批量抓取等

 

設置方式通常為

*fetch="join",hibernate會通過一個select語句連接(內聯/外聯)抓取其關聯對象或集合

*fetch="subselect",另外發送一條select語句抓取在前面查詢到的所有實體的關聯集合

*可以使用fetch預抓取Classes,解決N+1問題,hql中使用“join fetch ” ,select s from Student s join fetch s.classes  where s.id in(:ids)

*batch-size屬性,可以批量加載實體類

 

(二)緩存

緩存原則:通常讀遠遠大于寫的數據進行緩存

 

Hibernate的Session在事務級別進行持久化數據的緩存操作。 當然,也有可能分別為每個類(或集合),配置集群、或JVM級別(SessionFactory級別)的緩存。 你甚至可以為之插入一個集群的緩存。注意,緩存永遠不知道其他應用程序對持久化倉庫(數據庫)可能進行的修改 (即使可以將緩存數據設定為定期失效)。

 

1、一級緩存

 

一級緩存生命周期很短和session的生命周期一致,一級緩存也叫session級的緩存或事務級緩存

 

* load/get/iterate查詢實體對象時,支持一級緩存

 

* 一級緩存是緩存實體對像的,對屬性不緩存

 

*對于 大批量的數據添加

 

session.beginTransaction();

for (int i=0; i<100000; i++) {

Student student = new Student();

student.setName("張三" + i);

session.save(student);

//每20條更新一次

if (i % 20 == 0) {

session.flush();

//清除緩存的內容

session.clear();

}

}

session.getTransaction().commit();

 

 

2、二級緩存

 

二級緩存也稱為進程級的緩存或SessionFactory級的緩存,二級緩存可以被所有的session共享

 

二級緩存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二級緩存

 

二級緩存的配置和使用:

* 將ehcache.xml文件拷貝到src下

* 在hibernate.cfg.xml文件中加入緩存產品提供商

<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

* 啟用二級緩存,這也是它的默認配置

<property name="hibernate.cache.use_second_level_cache">true</property>

* 指定哪些實體類使用二級緩存

可以在映射文件中采用<cache>標簽指定或在hibernate.cfg.xml文件中統一指定

如:

<!--

指定Student使用二級緩存

 -->

<class-cache class="com.bjpowernode.hibernate.Student" usage="read-only"/>

注意使用緩存的策略,通常采用read-only和read-write

 

 *二級緩存主要是緩存實體對象      

*如果要清除二級緩存中的某些對象

//HibernateUtils.getSessionFactory().evict(Student.class);

HibernateUtils.getSessionFactory().evict(Student.class, 1);

 

*注意大批量數據更新時,如果配置了二級緩存建議禁用一級緩存和二級緩存的交互

session.beginTransaction();

 

//禁止一級緩存和二級緩存交互

session.setCacheMode(CacheMode.IGNORE);

for (int i=0; i<100; i++) {

Student student = new Student();

student.setName("張三" + i);

session.save(student);

//每20條更新一次

if (i % 20 == 0) {

session.flush();

//清除緩存的內容

session.clear();

}

}

session.getTransaction().commit();

 

(三)查詢緩存

* 查詢緩存是緩存普通屬性結果集的

* 對實體對象的結果集會緩存id(在查詢緩存中,它并不緩存結果集中所包含的實體的確切狀態;它只緩存這些實體的標識符屬性的值、以及各值類型的結果。  )

 

查詢緩存的生命周期,當關聯的表發生修改,查詢緩存的生命周期結束

 

查詢緩存的配置和使用:

* 修改hibernate.cfg.xml文件,來開啟查詢緩存,默認是false是不起用的

<property name="hibernate.cache.use_query_cache">true</property>        

* 必須在程序啟用

query.setCacheable(true)

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