Spring+Hibernate處理大批量資料
阿新 • • 發佈:2019-01-09
原文:http://blog.csdn.net/ye1992/article/details/9291237
關於使用spring+hibernate進行大批量資料的插入和更新,它的效能和使用JDBC
PreparedStatement的batch批量操作以及資料庫的儲存過程操作幾乎可以一樣高。在Hibernate的官方文件裡說到了Batchprocessing。Spring+Hibernate大批量處理資料想要說明如何使用Hibernate大批量處理資料獲得高效能。
使用Hibernate將 100 000 條記錄插入到資料庫的一個很自然的做法可能是這樣的
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); for ( int i=0; i<100000; i++ ) { Customer customer = new Customer(.....); session.save(customer); } tx.commit(); session.close();
這段程式大概執行到 50 000條記錄左右會失敗並丟擲 記憶體溢位異常(OutOfMemoryException) 。這是因為 Hibernate 把所有新插入的 客戶(Customer)例項在session級別的快取區進行了快取的緣故。
我們會在本章告訴你如何避免此類問題。首先,如果你要執行批量處理並且想要達到一個理想的效能,那麼使用JDBC的批量(batching)功能是至關重要。將JDBC的批量抓取數量(batch size)引數設定到一個合適值(比如,10-50之間):
hibernate.jdbc.batch_size 20
你也可能想在執行批量處理時關閉二級快取:
hibernate.cache.use_second_level_cache false
14.1. 批量插入(Batch inserts)
如果要將很多物件持久化,你必須通過經常的呼叫 flush() 以及稍後呼叫 clear() 來控制第一級快取的大小。
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); for ( int i=0; i<100000; i++ ) { Customer customer = new Customer(.....); session.save(customer); if ( i % 20 == 0 ) { //20, same as the JDBC batch size //20,與JDBC批量設定相同 //flush a batch of inserts and release memory: //將本批插入的物件立即寫入資料庫並釋放記憶體 session.flush(); session.clear(); } } tx.commit(); session.close();
14.2. 批量更新(Batch updates)
此方法同樣適用於檢索和更新資料。此外,在進行會返回很多行資料的查詢時,你需要使用 scroll() 方法以便充分利用伺服器端遊標所帶來的好處。
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); ScrollableResults customers = session.getNamedQuery("GetCustomers") .setCacheMode(CacheMode.IGNORE) .scroll(ScrollMode.FORWARD_ONLY); int count=0; while ( customers.next() ) { Customer customer = (Customer) customers.get(0); customer.updateStuff(...); if ( ++count % 20 == 0 ) { //flush a batch of updates and release memory: session.flush(); session.clear(); } } tx.commit(); session.close();