Hibernate 批量插入、更新与删除
来源:互联网 发布:淘宝数据魔方在哪里看 编辑:程序博客网 时间:2024/05/08 05:52
(1):优化Hibernate,程序上采用分段插入及时清除缓存的方法。
(2):绕过Hibernate API ,直接通过 JDBC API 来做批量插入,这个方法性能上是最好的,也是最快的。
对于上述中的方法1,其基本是思路为:优化Hibernate,在配置文件中设置hibernate.jdbc.batch_size参数,来指定每次提交SQL的数量;程序上采用分段插入及时清除缓存的方法(Session实现了异步write-behind,它允许Hibernate显式地写操作的批处理),也就是每插入一定量的数据后及时的把它们从内部缓存中清除掉,释放占用的内存。
设置hibernate.jdbc.batch_size参数,可参考如下配置。
<hibernate-configuration>
<session-factory>
.........
<propertyname=” hibernate.jdbc.batch_size”>50</property>
.........
<session-factory>
<hibernate-configuration>
配置hibernate.jdbc.batch_size参数的原因就是尽量少读数据库,hibernate.jdbc.batch_size参数值越大,读数据库的次数越少,速度越快。从上面的配置可以看出,Hibernate是等到程序积累到了50个SQL之后再批量提交。笔者也在想,hibernate.jdbc.batch_size参数值也可能不是设置得越大越好,从性能角度上讲还有待商榷。这要考虑实际情况,酌情设置,一般情形设置30、50就可以满足需求了。
程序实现方面,笔者以插入10000条数据为例子,如
Session session=HibernateUtil.currentSession();
Transatcion tx=session.beginTransaction();
for(inti=0;i<10000;i++)??? Studentst=new Student();
st.setName(“feifei”);
session.save(st);
// 以每50个数据作为一个处理单元
if(i%50==0)??
{
//只是将Hibernate缓存中的数据提交到数据库,保持与数据库数据的同步
session.flush();??
//?清除内部缓存的全部数据,及时释放出占用的内存
session.clear();??
}
}
tx.commit();
.........
在一定的数据规模下,这种做法可以把系统内存资源维持在一个相对稳定的范围。???注意:前面提到二级缓存,笔者在这里有必要再提一下。如果启用了二级缓存,从机制上讲Hibernate为了维护二级缓存,我们在做插入、更新、删除操作时,Hibernate都会往二级缓存充入相应的数据。性能上就会有很大损失,所以笔者建议在批处理情况下禁用二级缓存。???对于方法2,采用传统的JDBC的批处理,使用JDBC API来处理。
些方法请参照java批处理自执行SQL
看看上面的代码,是不是总觉得有不妥的地方?对,没发现么!这还是JDBC的传统编程,没有一点Hibernate味道。
可以对以上的代码修改成下面这样:
Transaction tx=session.beginTransaction(); //使用Hibernate事务处理
边界Connection conn=session.connection();
PrepareStatement stmt=conn.prepareStatement(“insert into T_STUDENT(name)values(?)”);
for(intj=0;j++;j<200)...{
for(inti=0;i++;j<50)stmt.setString(1,”feifei”);
}
}
stmt.executeUpdate();
tx.commit(); //使用Hibernate事务处理边界
.........
这样改动就很有Hibernate的味道了。笔者经过测试,采用JDBC API来做批量处理,性能上比使用HibernateAPI要高将近10倍,性能上JDBC 占优这是无疑的。
批量更新与删除???Hibernate2中,对于批量更新操作,Hibernate是将符合要求的数据查出来,然后再做更新操作。批量删除也是这样,先把符合条件的数据查出来,然后再做删除操作。???(1):占用大量的内存。
(2):处理海量数据的时候,执行update/delete语句就是海量了,而且一条update/delete语句只能操作一个对象,这样频繁的操作数据库,性能低下应该是可想而知的了。
Hibernate3 发布后,对批量更新/删除操作引入了bulkupdate/delete,其原理就是通过一条HQL语句完成批量更新/删除操作,很类似JDBC的批量更新/删除操作。在性能上,比Hibernate2的批量更新/删除有很大的提升。
Transaction tx=session.beginSession();
String HQL=”delete STUDENT”;
Query query=session.createQuery(HQL);
int size=query.executeUpdate();
tx.commit();
.......
控制台输出了也就一条删除语句Hibernate:delete fromT_STUDENT,语句执行少了,性能上也与使用JDBC相差无几,是一个提升性能很好的方法。当然为了有更好的性能,笔者建议批量更新与删除操作还是使用JDBC,方法以及基本的知识点与上面的批量插入方法2基本相同,这里就不在冗述。???笔者这里再提供一个方法,就是从数据库端来考虑提升性能,在Hibernate程序端调用存储过程。存储过程在数据库端运行,速度更快。以批量更新为例,给出参考代码。
首先在数据库端建立名为batchUpdateStudent存储过程:
createor replace produre batchUpdateStudent(a in number) as
begin
update STUDENT set AGE=AGE+1where AGE>a;
end;Transaction tx=session.beginSession();
Connection conn=session.connection();
String pd=”...{callbatchUpdateStudent(?)}”;
CallableStatement cstmt=conn.PrepareCall(pd);
cstmt.setInt(1,20);//把年龄这个参数设为20
tx.commit();观察上面的代码,也是绕过Hibernate API,使用 JDBCAPI来调用存储过程,使用的还是Hibernate的事务边界。存储过程无疑是提高批量处理性能的一个好方法,直接运行与数据库端,某种程度上讲把批处理的压力转接给了数据库。
三:编后语
本文探讨了Hibernate的批处理操作,出发点都是在提高性能上考虑了,也只是提供了提升性能的一个小方面。
不管采取什么样的方法,来提升性能都要根据实际的情况来考虑,为用户提供一个满足需求的而且高效稳定的系统才是重中之中。
原文链接:http://hi.baidu.com/liuhongsen/item/803b8535ddce6f4f3075a180
- Hibernate 批量插入、更新与删除
- Hibernate 批量插入、更新与删除
- Hibernate 批量插入、更新与删除
- Hibernate 批量插入、更新与删除
- Hibernate批处理操作优化 (批量插入、更新与删除)
- Hibernate批处理操作优化 (批量插入、更新与删除)
- Hibernate批处理操作优化 (批量插入、更新与删除)
- Hibernate批处理操作优化 (批量插入、更新与删除)
- Hibernate批处理操作优化 (批量插入、更新与删除)
- Hibernate批处理操作优化 (批量插入、更新与删除)
- Hibernate批处理操作优化 (批量插入、更新与删除)
- Hibernate批处理操作优化 (批量插入、更新与删除)
- Hibernate批处理操作优化 (批量插入、更新与删除)
- Hibernate 批量更新与删除
- hibernate批量删除与更新
- hibernate批量插入,更新和删除!
- Hibernate批量更新与批量删除
- hibernate批量更新与批量删除
- 黑马程序员-继承性、多态性
- FZU汇编作业 实验(四)
- 2014年计算机求职总结--准备篇
- 条件码及其访问
- web开发 笔记 - 中文编码问题
- Hibernate 批量插入、更新与删除
- 析构函数的定义
- 在ubuntu12.04上安装部署foreman
- 仿照linux dpm机制,实现自己的dpm
- C++构造函数、复制构造函数、赋值操作符、析构函数--个人总结
- 黑马程序员_java基础知识总结(2)递归用法总结
- rsync + inotify-tools 实现web发布目录同步
- poj1273_EK模板_dinic模板
- /proc——虚拟文件系统