標籤:des style class blog code java
批量處理資料是指在一個事務中處理大量資料.
在應用程式層進行大量操作, 主要有下面方式:
- 通過 Session
- 通過 HQL
- 通過 StatelessSession
- 通過 JDBC API(僅僅要會用這樣的,其它作為瞭解)
通過 Session 來進行大量操作Session 的 save() 及 update() 方法都會把處理的對象存放在自己的緩衝中. 假設通過一個 Session 對象來處理大量持久化對象, 應該及時從緩衝中清空已經處理完成而且不會再訪問的對象. 詳細的做法是在處理完一個對象或小批量對象後, 馬上調用 flush() 方法重新整理緩衝, 然後在調用 clear() 方法清空緩衝
通過 Session 來進行處理操作會受到下面約束
- 須要在 Hibernate 設定檔裡設定 JDBC 單次批量處理的數目, 應保證每次向資料庫發送的批量的 SQL 陳述式數目與 batch_size 屬性一致
- 若對象採用 “identity” 標識符產生器, 則 Hibernate 無法在 JDBC 層進行批量插入操作
- 進行大量操作時, 建議關閉 Hibernate 的二級緩衝
- 批次更新: 在進行批次更新時, 假設一下子把全部對象都載入到 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的事件處理系統忽略掉。
public class HibernateTest {private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic void init(){Configuration configuration = new Configuration().configure();ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()) .buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);session = sessionFactory.openSession();transaction = session.beginTransaction();}@Afterpublic void destroy(){transaction.commit();session.close();sessionFactory.close();}@Testpublic void testBatch(){session.doWork(new Work() {@Overridepublic void execute(Connection connection) throws SQLException {//通過 JDBC 原生的 API 進行操作, 效率最高, 速度最快!}});}}