本文詳細分析了Hibernate管理Session和批次操作的用法。分享給大家供大家參考。具體分析如下:
Hibernate管理Session
Hibernate本身提供了三種管理Session物件的方法① Session物件的生命週期與本地執行緒綁定② Session物件的生命週期與JTA事務綁定③ Hibernate委託程式管理Session物件的生命週期
在Hibernate的設定檔中,hibernate.current_session_context_class屬性用於指定Session管理方式,可選值包括:
① thread:Session物件的生命週期與本機執行緒綁定② jta*:Session物件的生命週期與JTA事務綁定③ managed:Hibernate委託程式來管理Session物件的生命週期
Session物件的生命週期與本地執行緒綁定:
如果把Hibernate設定檔的hibernate.current_session_context_class屬性值設定為thread,Hibernate就會依照與本機執行緒綁定的方式來管理Session
Hibernate以以下規則把Session與本地線程綁定:
當一個執行緒(thread)第一次呼叫SessionFactory物件的getCurrentSession()方法時,該方法會建立一個新的Session(sessionA)對象,把該物件與threadA綁定,並將session傳回當threadA再次呼叫SessionFactory對象的getCurrentSession()方法時,該方法將傳回sessionA物件當threadA提交sessionA物件關聯的事務時,Hibernate會自動flush sessionA物件的緩存,然後提交事務,關閉session隨心所欲。當threadA撤銷sessionA物件關聯的事務時,也會自動關閉sessionA物件若threadA再次呼叫SessionFactory物件的getCurrentSession()方法時,該方法會又建立一個新的Session(sessionB)對象,把該物件與threadA綁定,並將sessionB傳回
大量處理數據
批量處理資料是指在一個事務中處理大量資料在應用層進程批量操作,主要有以下方式:
① 透過Session
② 通過HQL
③ 透過StatelessSession
④ 透過JDBC API----推薦此種,因為速度最快
Session進行批量操作:
Session的save()及update()方法都會把處理過的物件存放在自己的快取中。如果透過一個Session對象來處理大量持久化對象,應該及時從快取中清空已經處理完畢並且不會再存取的對象。具體的做法是在處理完一個物件或小批量物件後,立即呼叫flush()方法刷新緩存,然後再呼叫clear()方法情況緩存
透過Session來進行處理操作會受到以下約束:
需要在Hibernate設定檔中設定JDBC單次批次處理的數目,應確保每次傳送至資料庫的批次的SQL語句數目與batch size屬性一致
若物件採用"identity"標識產生器,則Hibernate無法在JDBC曾進行批次插入操作
進行批次操作時,建議關閉Hibernate的二級快取
批量插入資料代碼演示:
複製程式碼如下:News news = null;
for(int i = 0; i < 10000; i++) {
news = new News();
news.setTitle("--" + i);
session.save(news);
if((i + 1) % 20 == 0) {
session.flush();
session.clear();
}
}
批次更新:在進行批次更新時,如果一下子把所有物件都載入到Session緩存,然後再緩存中一一更新,顯然是不可取的
使用可捲動的結果集org.hibernate.ScrollableResults,該對像中實際上並不包含任何對象,只包含用於線上定位記錄的遊標。只有當程式遍歷存取ScrollableResults物件的特定元素時,它才會到資料庫中載入對應的對象
org.hibernate.ScrollableResults物件由Query的scroll方法傳回
透過HQL進行批次操作:
注意:HQL只支援INSERT INTO ... SELECT形式的插入語句,但不支援INSERT INTO ... VALUES形式的插入語句。所以使用HQL不能進行批次插入操作
透過StatelessSession進行批次操作:
從形式上看,StatelessSession與Session的用法類似。 StatelessSession與Session相比,有以下差異:
StatelessSession沒有緩存,透過StatelessSession來載入、儲存或更新後的物件處於遊離狀態
StatelessSession不會與Hibernate的二級快取互動當呼叫StatelessSession的save()、update()或delete()方法時,這些方法會立即執行對應的SQL語句,而不會只計畫執行一條SQL語句
StatelessSession不會進行髒檢查,因此修改了Customer物件屬性後,還需要呼叫StatelessSession的update()方法來更新資料庫中數據
StatelessSession不會對關聯的物件進行任何的級聯操作透過同一個StatelessSession物件兩次載入的OID為1的Customer對象,得到的兩個物件記憶體位址不同
StatelessSession所做的操作可以被Interceptor攔截器捕捉到,但會被Hibernate的事件處理系統忽略掉
希望本文所述對大家的Java程式設計有幫助。