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的数量;