在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;

时间: 2024-11-02 18:50:00

在Hibernate中处理批量更新和批量删除的相关文章

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

以下程序直接通过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

mysql 批量更新与批量更新多条记录的不同值实现方法_Mysql

批量更新 mysql更新语句很简单,更新一条数据的某个字段,一般这样写: 复制代码 代码如下: UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value'; 如果更新同一字段为同一个值,mysql也很简单,修改下where即可: 复制代码 代码如下:  UPDATE mytable SET myfield = 'value' WHERE other_field in ('other_values');  这里注意

mysql 批量更新与批量更新多条记录的不同值

批量更新 mysql更新语句很简单,更新一条数据的某个字段,一般这样写:  代码如下 复制代码 UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value'; 如果更新同一字段为同一个值,mysql也很简单,修改下where即可:  代码如下 复制代码  UPDATE mytable SET myfield = 'value' WHERE other_field in ('other_values'); 这里注意 '

LINQ To SQL在N层应用程序中的CUD操作、批量删除、批量更新

原文:LINQ To SQL在N层应用程序中的CUD操作.批量删除.批量更新 0. 说明     Linq to Sql,以下简称L2S.    以下文中所指的两层和三层结构,分别如下图所示:       准确的说,这里的分层并不是特别明确:(1) 生成的DataContext(Linq t0 SQL Runtime)和Entity是放在一个文件中的,物理上不能切割开来:上图只是展示逻辑上的结构.(2) 拿上图右边的三层结构来说,鉴于第(1)点,UI层就可以跨越BusinessLogic层,直接

ORACLE中如何批量更新关联表

在SQL SERVER中,关联表的批量更新,可以参看这里: http://www.cnblogs.com/downmoon/archive/2007/12/29/1019832.html Oracle下没找到好的语法,临时用这个: update employee set hrdeptname= (select d.DEPTNAME from DEPARTMENT d where ROWNUM=1 and d.deptID=employee.hrdeptID ) 对应的SQL Server语法:

使用IBM Cognos批量更新报告中的图像URL

本文本文旨在提供一种疑难解答方法,整合公开可用的实用程序来诊断和解决在特定用例中识别出的问题.该用例将显示为一种场景,IBM Cognos 支持分析师可以在该场景中与客户合作诊断和解决特定的问题. 适用性 尽管列出的疑难解答方法不是 IBM Cognos BI 版本所独有的,但使用的一些诊断实用程序是独有的.要下载的实用程序版本取决于出问题的 IBM Cognos BI 版本. 用例描述 在此场景中,一位客户询问支持分析师如何轻松而又快速地更新多个报告中找到的某个图像路径.客户指出他们有多个报告

如何在GridView中一次性批量更新多行数据

假定有一个Product表,字段有(Id,Name,Quantity,...)我们要一次批量更新Quantity的值     首先在Gridview中,Quantity列以TemplateField显示,其他的列属性设为只读,把显示格式设为TextBox <asp:TemplateField HeaderText="Quantity">   <ItemTemplate>     <asp:TextBox ID="editQuantity"

批量更新日期字段中的年

工作需要,将数据中的日期字段中的年批量更新到指定的年,想了一下,写成这样:如:批量更新到DateAdd(year,-5,GETDATE()) =2002 SET oDateTime=DateAdd(year,Datediff(year,oDateTime,DateAdd(year,-5,GETDATE())),oDateTime) 不知道sql里面有没有更简单的方法.好像Oracle里面有一个date什么的函数,可以用正则去替换,不知道sql里面有没有. 记录一下,有时间再研究一下.

在ASP.NET 2.0中操作数据之六十二:GridView批量更新数据_自学过程

导言: 在前面的教程,我们对数据访问层进行扩展以支持数据库事务.数据库事务确保一系列的操作要么都成功,要么都失败.本文我们将注意力转到创建一个批更新数据界面. 在本文,我们将创建一个GridView控件,里面的每一行记录都可以进行编辑(见图1),因此我们没有必要多添加一列来包含Edit, Update,和Cancel按钮,而是在页面包含2个"Update Products"按钮,被点击时,遍历所有的产品并对数据库进行更新.让我们开始吧. 图1:GridView控件里的每一行记录都可以编