您的位置:首页 > 编程语言 > Java开发

【java】itoo项目实战之hibernate 批量保存优化

2015-07-27 07:32 741 查看
在itoo中,基本上每个系统都有一个导入功能,大量的数据填写进入excel模板中,然后使用导入功能导入的数据库中,这样可以大大的提高工作效率。那么导入就涉及到了批量保存数据库的问题了。
那么通常情况下,在一个Session对象的缓存中数量有限的持久化对象,等到Session对象处理事务完毕,还要关闭Session对象,从而及时释放session的缓存占用的内存。在批量保存1万条数据,如果一次性把需要保存的1万条数据加载到内存职工,当执行事务提交的时候,就会清理缓存,hibernate执行1万条更新语句。这样更新的方式有两个缺点:
(1)占用大量内存,必须把1万条加载到内存中,然后一一更新它们。
(2)执行的update数目过多,每个update语句只能更新一条数据,必须通过1万条update语句才能更新1万条数据,频繁地访问数据库,会大大降低应用的性能。
对于以上的情况,咱们可以通过Session来进行批量操作,Session
的sava方法都会把处理对象的存放在自己的缓存职工,如果通过一个Session对象来处理大量持久化对象,应该及时从缓存中清空已经处理完毕并且不会在访问的对象。具体的做法就是处理完一个对象或者小批量对象后,立刻调用Flush()方法清理缓存,然后再调用Clear()方法清空缓存。

如果通过Session来进行批量操作,会受到以下的约束:

1.需要在hibernate的配置文件中设置JDBC单次批量处理的数目,合理的取值通常为10~50,例如hibernate.jdbc.batch_size=30;这样设置的,就需要保证每次像数据库发送的批量SQL语句数目与这个batch_size属性一致。

2.如果操作对象采用"identity"标识符生成器,则Hibernate无法在JDBC层进行批量插入操作。

3.进行批量操作时,建议关闭hibernate的第二级缓存,Session的缓存为hibernate的第一级缓存,通常它是事务范围内的缓存,每个事务都有单独的第一级缓存。SessionFactory的外置缓存为Hibernate的第二级荤菜,它是应用范围内的缓存,所有的事务都共享同一个第二级缓存。在任何情况下,hibernate的第一级缓存总是可用的,在默认情况下,hibernate的第二级缓存是关闭的,但是也可以在hibernate的配置文件中手动关闭二级缓存:
Hibernate.cache.use_second_level_cache=false;

在itoo中批量保存的代码如下:

<span style="font-family:FangSong_GB2312;font-size:18px;">/**
 * 批量保存
 *
 * @param list
 *            list类型
 * @return 返回boolean值
 */
public <T> boolean saveEntitys(List<T> list) {
boolean flag = false;
int batchSize = 30;
int i = 0;
getDataBaseName(list.get(0));
try {
for (Object entity : list) {
getEntityManager().persist(entity);
i++;
if (i % batchSize == 0) {
getEntityManager().flush();
getEntityManager().clear();
}
}
flag = true;
} catch (Exception e) {
 
}
return flag;
}</span>


在以上的程序中,每次执行session.flush()方法,就会向数据库职工批量插入30条记录。接下来session.clear()方法把20个刚保存的对象从缓存中清空。

只要是设计有批量导入的情况,都会涉及到批量保存的内容,这篇博客就是让你的批量保存达到最优效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: