`
lzkyo
  • 浏览: 468189 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

在Hibernate3应用中如何处理批量更新和批量删除(修正版)

阅读更多
批量更新是指在一个事务中更新大批量数据,批量删除是指在一个事务中删除大批量数据。以下程序直接通过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语句中更新或删除大批量的数据。

 

 

Hibernate3.0对批量更新和批量删除提供了支持,能够直接执行批量更新或批量删除语句,无需把被更新或删除的对象先加载到内存中。以下是通过Hibernate3.0执行批量更新的程序代码:

代码
  1. Session session = sessionFactory.openSession();    
  2. Transaction tx = session.beginTransaction();    
  3. String hqlUpdate = "update Customer set name = :newName where name =<img src="/images/forum/smiles/icon_surprised.gif"/>ldName";    
  4. int updatedEntities = s.createQuery( hqlUpdate )    
  5. .setString( "newName", newName )    
  6. .setString( "oldName", oldName )    
  7. .executeUpdate();    
  8. tx.commit();    
  9. session.close();   

以下是通过Hibernate3.0执行批量删除的程序代码:

代码
  1. Session session = sessionFactory.openSession();    
  2. Transaction tx = session.beginTransaction();    
  3. String hqlDelete = "delete Customer where name =<img src="/images/forum/smiles/icon_surprised.gif"/>ldName";    
  4. int deletedEntities = s.createQuery( hqlDelete )    
  5. .setString( "oldName", oldName )    
  6. .executeUpdate();    
  7. tx.commit();    
  8. session.close();   
分享到:
评论

相关推荐

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

    然而,在处理大量数据时,如何有效地执行批量更新和批量删除操作成为了许多开发者面临的挑战。本文将深入探讨在Hibernate应用中处理批量更新和批量删除的最佳实践,以及如何避免常见的性能陷阱。 ### 一、批量更新...

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

    然而,在处理大量数据时,如何有效地进行批量更新和批量删除操作,是每一个开发者都可能遇到的挑战。本文将深入探讨在Hibernate中处理批量更新和批量删除的策略,以及如何优化这些操作,以提高数据库操作的效率。 #...

    Hibernate中大量数据的更新

    本文将讨论使用 Hibernate 批量更新大量数据的方法和技巧。 批量更新的必要性 在实际应用中,我们经常需要将大量数据插入到数据库中,例如数据迁移、数据同步、数据备份等场景。在这些场景中,如果使用传统的 ...

    Hibernate下数据批量处理解决方案

    总的来说,虽然ORM框架在处理大数据时可能存在性能挑战,但通过合理配置和使用批处理、游标滚动以及适时的缓存管理,我们可以克服这些挑战,使Hibernate在批量数据处理中发挥高效的作用。在实际项目中,还应结合...

    hibernate批量删除

    在Java开发中,处理大量数据时,经常需要执行批量操作,如批量更新或批量删除。这些操作对于提高应用程序性能至关重要,尤其是在涉及成千上万条记录的情况下。Hibernate作为一款流行的Java持久层框架,支持通过其...

    jsp Hibernate批量更新和批量删除处理代码.docx

    本文件主要探讨了如何使用Hibernate进行批量更新和批量删除处理,这些操作在处理大量数据时尤其重要,因为它们可以显著提高应用的性能。下面我们将深入解析这两个主题。 批量更新在Hibernate中通常涉及在一个事务中...

    jsp Hibernate批量更新和批量删除处理代码

    本文将详细介绍如何在使用JSP和Hibernate环境下进行高效的批量更新与删除操作。 ### 批量更新与批量删除 批量操作指的是在数据库层面一次性对大量数据进行更新或删除。与单条记录的更新或删除相比,批量操作能大幅...

    JSF+hibernate实现批量删除

    本篇文章将详细探讨如何利用JSF与Hibernate相结合来实现批量删除功能,以及在CRUD(创建、读取、更新和删除)操作中的应用。 首先,我们需要理解JSF的工作原理。JSF是一个基于组件的MVC(Model-View-Controller)...

    struts2 hibernate spring 整合批量删除源码

    Struts2、Hibernate和Spring是Java Web开发中的三大框架,它们各自负责不同的职责,而将它们整合在一起可以构建出高效、灵活的企业级应用。在这个批量删除的源码中,我们可以看到这三个框架协同工作的实例。 首先,...

    Hibernate批量处理

    批量处理对于需要在短时间内处理大量数据的应用尤其重要,如批量更新、批量插入或批量删除等场景。 #### 二、批量处理的必要性 在实际开发过程中,当需要处理大量数据时,传统的逐条处理方式不仅占用大量的内存...

    hibernate3应用实例

    hibernate3应用实例hibernate3应用实例hibernate3应用实例hibernate3应用实例

    Hibernate批量处理数据

    因此,本文将详细介绍Hibernate如何高效地进行批量数据处理,包括批量插入、批量更新和批量删除。 #### 二、批量插入 在批量插入数据时,直接使用循环逐一保存的方式容易导致内存溢出。这是因为Hibernate的Session...

    Hibernate Web应用的开发步骤

    Hibernate Web应用的开发一般经过以下几个步骤: (1)创建数据库。 (2)将Hibernate所需的JAR包复制到WEB-INF/lib下。 (3)创建Hibernate的配置文件。 (4)利用Hibernate的第三方工具或Eclipse的有关插件从...

    hibernate3 hibernate3

    在本篇文章中,我们将深入探讨Hibernate3的核心概念、主要功能以及如何在实际项目中应用。 一、Hibernate3核心概念 1. 实体(Entity):在Hibernate中,实体代表数据库中的表,是Java类的一个实例。通过在类上使用...

    浅析Hibernate下数据批量处理方法.doc

    对于批量更新和删除操作,可以使用`scroll()`方法配合查询命名(NamedQuery),以滚动结果集的方式处理数据。这样可以在遍历数据的同时,分批处理并提交事务,同样通过调用`flush()`和`clear()`来管理内存。 然而,...

    2022年Hibernate下数据批量处理Java教程.docx

    在批量更新数据时,我们可以使用 Hibernate 的 ScrollableResults 对象。例如: ``` Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); ScrollableResults customers ...

    hibernate3.zip 包含hibernate3.jar

    2. **Session**:在Hibernate中,`Session`对象是数据库会话的代表,负责在应用程序和数据库之间建立连接。它可以执行查询、保存、更新和删除对象,同时提供事务管理和缓存功能。 3. **SessionFactory**:`...

    Java中Hibernate的批量插入

    然而,在处理大量数据的批量操作时,如批量插入、更新或删除,如果不采取适当的策略,可能会导致性能问题甚至出现内存溢出异常。针对这种情况,Hibernate提供了一些批量处理的解决方案。 批量插入是处理大量数据...

    Hibernate3的依赖包

    在这个"Hibernate3的依赖包"中,包含了运行Hibernate3应用程序所需的一系列库文件,这些库文件是实现ORM功能的关键组成部分。 在Java开发中,Hibernate3依赖包的引入是为了支持以下核心功能: 1. **对象关系映射...

    关于Clob类型在Hibernate中 的应用小结

    Clob”类型在数据库中主要用于存储大对象(Large Object),...总的来说,理解和掌握Clob在Hibernate中的应用对于开发处理大文本数据的系统至关重要。通过合理的配置和使用,可以有效地管理并操作大量的非结构化数据。

Global site tag (gtag.js) - Google Analytics