很多人都对Java在批量数据的处理方面是否是其合适的场所持有怀疑的念头由此延伸那么就会认为ORM可能也不是非凡适合数据的批量处理其实我想假如我们应用得当的话完全可以消除ORM批量处理性能问题这方面的顾虑下面以Hibernate为例来做为说明假如我们真的不得不在 Java中使用Hibernate来对数据进行批量处理的话 向数据库插入 条数据用Hibernate可能像这样
Session session = sessionFactory
openSession();
Transaction tx = sessionbeginTransaction();
for ( int i=; i<; i++ ) {
Customer customer = new Customer();
sessionsave(customer); }
txcommit();
sessionclose();
大概在运行到第 条的时候就会出现内存溢出而失败这是Hibernate把最近插入的Customer都以sessionlevel cache在内存做缓存我们不要忘记Hiberante并没有限制firstlevel cache 的缓存大小
◆持久对象实例被治理在事务结束时此时Hibernate与数据库同步任何已经发生变 化的被治理的的对象
◆Session实现了异步writebehind它答应Hibernate显式地写操作的批处理 这里我给出Hibernate如何实现批量插入的方法
首先我们设置一个合理的JDBC批处理大小hibernatejdbcbatch_size 然后在一定间隔对Session进行flush()和clear()
Session session = sessionFactory
openSession();
Transaction tx = sessionbeginTransaction();
for ( int i=; i<; i++ ) {
Customer customer = new Customer();
sessionsave(customer);
if ( i % == ) {
//flush 插入数据和释放内存:
sessionflush(); sessionclear(); }
}
txcommit();
sessionclose();
那么关于怎样删除和更新数据呢?那好在Hibernate或者更后版本scroll() 这个方法将是最好的途径
Session session = sessionFactory
openSession();
Transaction tx = sessionbeginTransaction();
ScrollableResults customers = sessiongetNamedQuery(GetCustomers)
scroll(ScrollModeFORWARD_ONLY);
int count=;
while ( customersnext() ) {
Customer customer = (Customer) customersget();
customerupdateStuff();
if ( ++count % == ) {
//flush 更新数据和释放内存:
sessionflush(); sessionclear(); } }
txcommit(); sessionclose();
这种做法并不困难也不算不优雅请注重假如Customer启用了secondlevel caching 我们仍然会有一些内存治理的问题原因就是对于用户的每一次插入和更新Hibernate在事务处理结束后不得不通告secondlevel cache 因此我们在批处理情况下将要禁用用户使用缓存