Hibernate完全以面向對象的方式來操作數據庫當程序裡以面向對象的方式操作持久化對象時將被自動轉換為對數據庫的操作例如我們調用Session的delete()方法來刪除持久化對象Hibernate將負責刪除對應的數據記錄當我們執行持久化對象的setter方法時Hibernate將自動轉換為底層的update語句修改數據庫的對應記錄
問題是如果我們需要同時更新條記錄是不是要逐一加載條記錄然後依次調用setter方法——這樣不僅煩瑣數據訪問的性能也十分糟糕為了面對這種批量處理的場景Hibernate提供了批量處理的解決方案下面分別從批量插入批量更新和批量刪除三個方面介紹如何面對這種批量處理的情形
批量插入
如果需要將條記錄插入數據庫通過Hibernate可能會采用如下做法
Session session = sessionFactoryopenSession();
Transaction tx = sessionbeginTransaction();
//循環次來插入條記錄
for ( int i=; i<; i++ )
{
User u = new User ();
sessionsave(u);
}
mit();
sessionclose();
但隨著這個程序的運行總會在某個時候運行失敗並且拋出OutOfMemoryException(內存溢出異常)這是因為Hibernate的Session持有一個必選的一級緩存所有的User實例都將在Session級別的緩存區進行了緩存的緣故
為了解決這個問題有個非常簡單的思路定時將Session緩存的數據刷入數據庫而不是一直在Session級別緩存可以考慮設計一個累加器每保存一個User實例累加器增加根據累加器的值決定是否需要將Session緩存中的數據刷入數據庫
下面是增加個User實例的代碼片段
程序清單codes\\\batchInsert\src\lee\UserManagerjava
private void addUsers()throws Exception
{
//打開Session
Session session = HibernateUtilcurrentSession();
//開始事務
Transaction tx = sessionbeginTransaction();
//循環次插入條記錄
for (int i = ; i < ; i++ )
{
//創建User實例
User u = new User();
usetName(xxxxx + i);
usetAge(i);
usetNationality(china);
//在Session級別緩存User實例
sessionsave(u);
//每當累加器是的倍數時將Session中數據刷入數據庫
//並清空Session緩存
if (i % == )
{
sessionflush();
sessionclear();
}
}
//提交事務
mit();
//關閉事務
HibernateUtilcloseSession();
}
上面的代碼中當i % == 時手動將Session處緩存的數據寫入數據並且清空Session緩存裡的數據除了要對Session級別緩存進行處理外還應該通過如下配置來關閉SessionFactory的二級緩存
hibernatecacheuse_second_level_cache false
注意除了要手動清空Session級別的緩存外最好關閉SessionFactory級別的二級緩存否則即使手動flush Session級別的緩存但因為在SessionFactory還有二級緩存也可能引發異常關於二級緩存的介紹請參考後面的內容
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28497.html