Hibernate之海量数据操作
- 批量添加
在实际的开发中,当我们遇到百万条以上的数据呢?比如要一次保存10万条的数据,按照我们正常的思维来,应该这么写:
session.beginTransaction(); for(int i = 0,i<=100000,i++){ TUser user = new TUser(); session.save("user No:"+i); } session.getTransaction().commit();
但是这样一来有什么问题呢?程序肯定会以OutOfMemoryError异常而终止!为什么会这样?原因是Hibernate在每次调用session.save()时,都会将此对象纳入自身的内部缓存进行管理,内部缓存(一级缓存)与二级缓存不一样,二级缓存可以设置指定其中的最大容量,但内部缓存并没有这样的限制;
一次加入1百万数据,随着循环,内存会被耗尽,便产生了OutOfMemoryError异常;
如何解决这样的问题?
- 首先看下在普通的JDBC里是如何解决?
String sql = "insert into TUser(name) values(?)"; PreparedStatement ps = conn.prepareStatement(sql); for(int i=0,i<1000000,i++){ ps.setString(1,"user "+i); ps.addBatch(); } int[] counts = ps.executeBatch();
这里的ps.addBatch()方法,将数个SQL操作批量提交获得性能上的提升;
- 在hibernate中的解决:
session.beginTransaction(); for(int i=0,i<1000000,i++){ TUser user = new TUser(); user.setName("user:"+i); session.save(user); if(i%25 == 0){ session.flush(); session.clear(); } } session.getTransaction().commit();
阶段性的调用session.clear();这样的话,可以将内部缓存(一级缓存)所占用的空间维持在一个合理的范围内;
但是这样的话,导入时,是个相当耗时的过程,然而还得在进行判断,效率的低,可想而知;这时,Hibernate给我们提供了更好的解决方案:
<property name="hibernate.jdbc.batch_size">25</property>
这样的话,就设定了Hibenrate每次提交SQL的数量;