很多人都對Java在批量數據的處理方面是否是其合適的場所持有懷疑的念頭由此延伸那麼就會認為ORM可能也不是非凡適合數據的批量處理其實我想假如我們應用得當的話完全可以消除ORM批量處理性能問題這方面的顧慮下面以Hibernate為例來做為說明假如我們真的不得不在 Java中使用Hibernate來對數據進行批量處理的話 向數據庫插入 條數據用Hibernate可能像這樣
Session session = sessionFactory
openSession();
Transaction tx = session
beginTransaction();
for ( int i=
; i<
; i++ ) {
Customer customer = new Customer(
);
session
save(customer); }
tx
commit();
session
close();
大概在運行到第 條的時候就會出現內存溢出而失敗這是Hibernate把最近插入的Customer都以sessionlevel cache在內存做緩存我們不要忘記Hiberante並沒有限制firstlevel cache 的緩存大小
◆持久對象實例被治理在事務結束時此時Hibernate與數據庫同步任何已經發生變 化的被治理的的對象
◆Session實現了異步writebehind它答應Hibernate顯式地寫操作的批處理 這裡我給出Hibernate如何實現批量插入的方法
首先我們設置一個合理的JDBC批處理大小hibernatejdbcbatch_size 然後在一定間隔對Session進行flush()和clear()
Session session = sessionFactory
openSession();
Transaction tx = session
beginTransaction();
for ( int i=
; i<
; i++ ) {
Customer customer = new Customer(
);
session
save(customer);
if ( i %
==
) {
//flush 插入數據和釋放內存:
session
flush(); session
clear(); }
}
tx
commit();
session
close();
那麼關於怎樣刪除和更新數據呢?那好在Hibernate或者更後版本scroll() 這個方法將是最好的途徑
Session session = sessionFactory
openSession();
Transaction tx = session
beginTransaction();
ScrollableResults customers = session
getNamedQuery(
GetCustomers
)
scroll(ScrollMode
FORWARD_ONLY);
int count=
;
while ( customers
next() ) {
Customer customer = (Customer) customers
get(
);
customer
updateStuff(
);
if ( ++count %
==
) {
//flush 更新數據和釋放內存:
session
flush(); session
clear(); } }
tx
commit(); session
close();
這種做法並不困難也不算不優雅請注重假如Customer啟用了secondlevel caching 我們仍然會有一些內存治理的問題原因就是對於用戶的每一次插入和更新Hibernate在事務處理結束後不得不通告secondlevel cache 因此我們在批處理情況下將要禁用用戶使用緩存
From:http://tw.wingwit.com/Article/program/Java/ky/201311/29193.html