我很喜欢Hibernate, 但我有时候还是使用自己的SQL Gernator..因为批处理数据,是非常消耗性能..
不过,最近翻hibernate 的blog , 对HIbernate的 批处理有了新的了解
插入10000条记录,比较坏的做法是:
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();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
}
tx.commit();
session.close();
这样子很快就会OutOfMenery, Hibernate在Session级别的时候,对所有新的对象作了缓存,我们一般都晓得要flush(),clear()一下来释放内存 .但频繁的这样会不会导致效率问题? 于是乎想到JDBC批处理的那种做法.
先设置
hibernate.jdbc.batch_size 20
然后,代码做一些小修改,这种做法 我们在JBDC的批处中,常这样干...
满20个一批addBatchUpdate...而这里则是flush(),clear();
满20个一批addBatchUpdate...而这里则是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 ) {
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
if ( i % 20 == 0 ) {
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();
如果是批量更新,那么最好的方法就是使用scroll() 方法 2.1.6以后版本都支持了.
代码如下:
代码如下:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
ScrollableResults customers = session.getNamedQuery("GetCustomers")
.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();
Transaction tx = session.beginTransaction();
ScrollableResults customers = session.getNamedQuery("GetCustomers")
.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();
还有个小警告: 这这种情况下,就不要对entity作缓存了...否则还是会有内存问题.
还是看原文比较好:)
原文:http://blog.hibernate.org/cgi-bin/blosxom.cgi/Gavin%20King/batch.html