【java】itoo項目實戰之hibernate 批量保存優化
在itoo中。基本上每一個系統都有一個導入功能,大量的數據填寫進入excel模板中。然後使用導入功能導入的數據庫中,這樣能夠大大的提高工作效率。
那麽導入就涉及到了批量保存數據庫的問題了。
那麽通常情況下,在一個Session對象的緩存中數量有限的持久化對象,等到Session對象處理事務完成,還要關閉Session對象,從而及時釋放session的緩存占用的內存。在批量保存1萬條數據,假設一次性把須要保存的1萬條數據載入到內存職工,當運行事務提交的時候,就會清理緩存,hibernate運行1萬條更新語句。
這樣更新的方式有兩個缺點:
(1)占用大量內存。必須把1萬條載入到內存中,然後一一更新它們。
(2)運行的update數目過多,每一個update語句僅僅能更新一條數據,必須通過1萬條update語句才幹更新1萬條數據。頻繁地訪問數據庫,會大大減少應用的性能。
對於以上的情況。咱們能夠通過Session來進行批量操作。Session 的sava方法都會把處理對象的存放在自己的緩存職工,假設通過一個Session對象來處理大量持久化對象,應該及時從緩存中清空已經處理完成而且不會在訪問的對象。
詳細的做法就是處理完一個對象或者小批量對象後,立馬調用Flush()方法清理緩存,然後再調用Clear()方法清空緩存。
假設通過Session來進行批量操作,會受到下面的約束:
1.
2.假設操作對象採用"identity"標識符生成器,則Hibernate無法在JDBC層進行批量插入操作。
3.進行批量操作時。建議關閉hibernate的第二級緩存。Session的緩存為hibernate的第一級緩存,通常它是事務範圍內的緩存。每一個事務都有單獨的第一級緩存。
SessionFactory的外置緩存為Hibernate的第二級葷菜,它是應用範圍內的緩存,全部的事務都共享同一個第二級緩存。在不論什麽情況下,
Hibernate.cache.use_second_level_cache=false;
在itoo中批量保存的代碼例如以下:
<span style="font-family:FangSong_GB2312;font-size:18px;">/** * 批量保存 * * @param list * list類型 * @return 返回boolean值 */ public <T> boolean saveEntitys(List<T> list) { boolean flag = false; int batchSize = 30; int i = 0; getDataBaseName(list.get(0)); try { for (Object entity : list) { getEntityManager().persist(entity); i++; if (i % batchSize == 0) { getEntityManager().flush(); getEntityManager().clear(); } } flag = true; } catch (Exception e) { } return flag; }</span>
在以上的程序中,每次運行session.flush()方法,就會向數據庫職工批量插入30條記錄。接下來session.clear()方法把20個剛保存的對象從緩存中清空。
僅僅要是設計有批量導入的情況,都會涉及到批量保存的內容,這篇博客就是讓你的批量保存達到最優效果。
【java】itoo項目實戰之hibernate 批量保存優化