`

在Hibernate应用中如何处理批量更新和批量删除【转】

阅读更多
批量更新是指在一个事务中更新大批量数据,批量删除是指在一个事务中删除大批量数据。以下程序直接通过Hibernate API批量更新CUSTOMERS表中年龄大于零的所有记录的AGE字段:
  
 tx = session.beginTransaction();
 Iterator customers=session.find("from Customer c where c.age>0").iterator();
 while(customers.hasNext()){
 Customer customer=(Customer)customers.next();
 customer.setAge(customer.getAge()+1);
 } 
 tx.commit();
 session.close();


如果CUSTOMERS表中有1万条年龄大于零的记录,那么Session的find()方法会一下子加载1万个Customer对象到内存。当执行tx.commit()方法时,会清理缓存,Hibernate执行1万条更新CUSTOMERS表的update语句:
  
 update CUSTOMERS set AGE=? …. where ID=i;
 update CUSTOMERS set AGE=? …. where ID=j;
 update CUSTOMERS set AGE=? …. where ID=k;


以上批量更新方式有两个缺点:

(1) 占用大量内存,必须把1万个Customer对象先加载到内存,然后一一更新它们。

(2) 执行的update语句的数目太多,每个update语句只能更新一个Customer对象,必须通过1万条update语句才能更新一万个Customer对象,频繁的访问数据库,会大大降低应用的性能。

为了迅速释放1万个Customer对象占用的内存,可以在更新每个Customer对象后,就调用Session的evict()方法立即释放它的内存:

tx = session.beginTransaction();
Iterator customers=session.find("from Customer c where c.age>0").iterator();
while(customers.hasNext()){
Customer customer=(Customer)customers.next();
customer.setAge(customer.getAge()+1);
session.flush();
session.evict(customer);
} 
tx.commit();
session.close();


在以上程序中,修改了一个Customer对象的age属性后,就立即调用Session的flush()方法和evict()方法,flush()方法使Hibernate立刻根据这个Customer对象的状态变化同步更新数据库,从而立即执行相关的update语句;evict()方法用于把这个Customer对象从缓存中清除出去,从而及时释放它占用的内存。

但evict()方法只能稍微提高批量操作的性能,因为不管有没有使用evict()方法,Hibernate都必须执行1万条update语句,才能更新1万个Customer对象,这是影响批量操作性能的重要因素。假如Hibernate能直接执行如下SQL语句:

update CUSTOMERS set AGE=AGE+1 where AGE>0;


那么以上一条update语句就能更新CUSTOMERS表中的1万条记录。但是Hibernate并没有直接提供执行这种update语句的接口。应用程序必须绕过Hibernate API,直接通过JDBC API来执行该SQL语句:
tx = session.beginTransaction();
Connection con=session.connection();
PreparedStatement stmt=con.prepareStatement("update CUSTOMERS set AGE=AGE+1 "
+"where AGE>0 ");
stmt.executeUpdate();
tx.commit();


以上程序演示了绕过Hibernate API,直接通过JDBC API访问数据库的过程。应用程序通过Session的connection()方法获得该Session使用的数据库连接,然后通过它创建PreparedStatement对象并执行SQL语句。值得注意的是,应用程序仍然通过Hibernate的Transaction接口来声明事务边界。

如果底层数据库(如Oracle)支持存储过程,也可以通过存储过程来执行批量更新。存储过程直接在数据库中运行,速度更加快。在Oracle数据库中可以定义一个名为batchUpdateCustomer()的存储过程,代码如下:
create or replace procedure batchUpdateCustomer(p_age in number) as
begin
update CUSTOMERS set AGE=AGE+1 where AGE>p_age;
end;


以上存储过程有一个参数p_age,代表客户的年龄,应用程序可按照以下方式调用存储过程:

tx = session.beginTransaction();
Connection con=session.connection();
String procedure = "{call batchUpdateCustomer(?) }";
CallableStatement cstmt = con.prepareCall(procedure);
cstmt.setInt(1,0); //把年龄参数设为0
cstmt.executeUpdate();
tx.commit();


从上面程序看出,应用程序也必须绕过Hibernate API,直接通过JDBC API来调用存储过程。

Session的各种重载形式的update()方法都一次只能更新一个对象,而delete()方法的有些重载形式允许以HQL语句作为参数,例如:
session.delete("from Customer c where c.age>0");


如果CUSTOMERS表中有1万条年龄大于零的记录,那么以上代码能删除一万条记录。但是Session的delete()方法并没有执行以下delete语句
delete from CUSTOMERS where AGE>0;

Session的delete()方法先通过以下select语句把1万个Customer对象加载到内存中:

select * from CUSTOMERS where AGE>0;

接下来执行一万条delete语句,逐个删除Customer对象:
delete from CUSTOMERS where ID=i;
delete from CUSTOMERS where ID=j;
delete from CUSTOMERS where ID=k;



由此可见,直接通过Hibernate API进行批量更新和批量删除都不值得推荐。而直接通过JDBC API执行相关的SQL语句或调用相关的存储过程,是批量更新和批量删除的最佳方式,这两种方式都有以下优点:

(1) 无需把数据库中的大批量数据先加载到内存中,然后逐个更新或修改它们,因此不会消耗大量内存。

(2) 能在一条SQL语句中更新或删除大批量的数据。
分享到:
评论

相关推荐

    在Hibernate应用中处理批量更新和批量删除

    在Hibernate应用中如何处理批量更新和批量删除

    Hibernate+中文文档

    1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. ...

    hibernate3.2中文文档(chm格式)

    1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. ...

    Hibernate中文详细学习文档

    1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. ...

    Hibernate 中文 html 帮助文档

    1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. ...

    HibernateAPI中文版.chm

    1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

    第3章 第一个Hibernate应用  3.1 创建Hibernate的配置文件  3.2 创建持久化类  3.3 创建数据库Schema  3.4 创建对象-关系映射文件  3.4.1 映射文件的文档类型定义(DTD)  3.4.2 把Customer持久化类映射到...

    tapestry hibernate Spring应用及组件的使用

    tapestry hibernate Spring应用及组件的使用的一个简单完整例子,包含form组件、table组件的一个增删改查。其中数据库创建用户和表在docs里,数据库使用oracle

    最全Hibernate 参考文档

    1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. 架构(Architecture) 2.1. 概况(Overview) 2.2. 实例状态 2.3. JMX整合 2.4. 对JCA的支持 3. 配置 ...

    hibernate3.04中文文档.chm

    1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

    第3章 第一个Hibernate应用  3.1 创建Hibernate的配置文件  3.2 创建持久化类  3.3 创建数据库Schema  3.4 创建对象-关系映射文件  3.4.1 映射文件的文档类型定义(DTD)  3.4.2 把Customer持久化类映射到...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

    第3章 第一个Hibernate应用  3.1 创建Hibernate的配置文件  3.2 创建持久化类  3.3 创建数据库Schema  3.4 创建对象-关系映射文件  3.4.1 映射文件的文档类型定义(DTD)  3.4.2 把Customer持久化类映射到...

    Hibernate教程

    Hibernate参考文档 目录 前言 1. 翻译说明 2. 版权声明 1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. Hibernate入门 2.1. 前言 2.2. 第...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

    第3章 第一个Hibernate应用  3.1 创建Hibernate的配置文件  3.2 创建持久化类  3.3 创建数据库Schema  3.4 创建对象-关系映射文件  3.4.1 映射文件的文档类型定义(DTD)  3.4.2 把Customer持久化类映射到...

    hibernate 体系结构与配置 参考文档(html)

    第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. 映射...

    Hibernate3+中文参考文档

    1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. 架构(Architecture) 2.1. 概况(Overview) 2.2. 实例状态 2.3. JMX整合 2.4. 对JCA的支持 3. 配置 ...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. ...

    最新JAVA通用后台管理系统(ExtJS 4.2+Hibernate 4.1.7+Spring MVC 3.2.8)Eclipse版本

    4、Grid列表和表单,包含添加、删除、批量删除、修改、查看、图片查看和按条件查询列表等功能。 5、导入导出Excel数据,支持xlsx和xls文件。 6、资源管理(菜单管理)。 7、用户管理和部门管理。 8、权限管理。不仅...

    Struts2和Hibernate框架实现图书管理系统

    10. 管理员可实现对用户的查询显示,模糊查询,删除,批量删除,全选和取消全选等功能;可实现对图书的查询显示,模糊查询,添加,删除,批量删除,全选和取消全选等功能。 11. 普通用户可实现借书和还书功能,借书...

Global site tag (gtag.js) - Google Analytics