jsp 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) asbeginupdate 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); //把年龄参数设为0cstmt.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语句中更新或删除大批量的数据。

(0)

相关推荐

  • Hibernate批量处理海量数据的方法

    本文实例讲述了Hibernate批量处理海量数据的方法.分享给大家供大家参考,具体如下: Hibernate批量处理海量其实从性能上考虑,它是很不可取的,浪费了很大的内存.从它的机制上讲,Hibernate它是先把符合条件的数据查出来,放到内存当中,然后再进行操作.实际使用下来性能非常不理想,在笔者的实际使用中采用下面的第三种优化方案的数据是:100000条数据插入数据库, 需要约30分钟,呵呵,晕倒.(本人10分钟插入1000000条数据(字段比较小)) 总结下来有三种来处理以解决性能问题:

  • Hibernate管理Session和批量操作分析

    本文详细分析了Hibernate管理Session和批量操作的用法.分享给大家供大家参考.具体分析如下: Hibernate管理Session Hibernate自身提供了三种管理Session对象的方法 ① Session对象的生命周期与本地线程绑定 ② Session对象的生命周期与JTA事务绑定 ③ Hibernate委托程序管理Session对象的生命周期 在Hibernate的配置文件中,hibernate.current_session_context_class属性用于指定Sess

  • 基于spring boot 1.5.4 集成 jpa+hibernate+jdbcTemplate(详解)

    1.pom添加依赖 <!-- spring data jpa,会注入tomcat jdbc pool/hibernate等 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <

  • hibernate批量操作实例详解

    本文实例讲述了hibernate批量操作的方法.分享给大家供大家参考,具体如下: Hibernate的批量处理 Hibernate完全以面向对象的方式来操作数据库,当程序里以面向对象的方式操作持久化对象时,将被自动转换为对数据库的操作.例如调用Session的delete()方法来删除持久化对象,Hibernate将负责删除对应的数据记录:当执行持久化对象的set方法时,Hibernate将自动转换为对应的update方法,修改数据库的对应记录. 问题是如果需要同时更新100 000条记录,是不

  • Hibernate实现批量添加数据的方法

    本文实例讲述了Hibernate实现批量添加数据的方法.分享给大家供大家参考,具体如下: 1.Hibernate_016_BatchAddData程序目录结构: 2.lib目录下所引入的jar包: 3.MedicineDao.java源代码: package com.xqh.dao; import java.util.List; import org.hibernate.Session; import com.xqh.model.Medicine; import com.xqh.

  • Hibernate+JDBC实现批量插入、更新及删除的方法详解

    本文实例讲述了Hibernate JDBC实现批量插入.更新及删除的方法.分享给大家供大家参考,具体如下: 一.批量插入(两种方式) 1. 通过Hibernate缓存 如果这样写代码进行批量插入(初始设想): package com.anlw.util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.

  • 解析使用jdbc,hibernate处理clob/blob字段的详解

    (1)不同数据库中对应clob,blob的类型:mysql中 : clob对应text  blob对应blobdb2/oracle中 clob对应clob blob对应blob (2)domain中对应类型:clob 对应 String   blob 对应 byte[]clob 对庆 java.sql.Clob blob 对应 java.sql.Blob (3)hibernate配置文件中对应类型:clob > clob   blob > binay 也可以直接使用数据库提供类型,例如:ora

  • jsp 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

  • Oracle中多表关联批量插入批量更新与批量删除操作

    该文章会分为三部分 1.多表关联批量插入 2.多表关联批量更新 3.多表关联批量删除 首先要明白一点,为什么会有批量这一个概念,无非就是数据太多了,在java端把数据查出来然后在按照100-300的批次进行更新太耗性能了,而且写出来的代码会非常的臃肿,所谓好的实现是用最少的,最精简的代码实现需求,代码越少,留给自己犯错误的机会更少. 还有一个知识点就是多表关联,对于查询肯定是可以多表关联的,其实对于除了查询之外也是可以进行多表关联过滤数据的,从而达到在Oracle中查到目标数据即可更新,从而规避

  • Yii2.0实现的批量更新及批量插入功能示例

    本文实例讲述了Yii2.0实现的批量更新及批量插入功能.分享给大家供大家参考,具体如下: 批量更新 方法1 /** * 批量更新循环周期 * @param array $condition * $condition = ['advertise_id' => '','status' => '', 'weekdays'=>[1,2,3]] 查询条件 * $params = ['status' => ''] * @param $params * @return bool */ publi

  • 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'); 这里注意 'o

  • 详解mybatis 批量更新数据两种方法效率对比

    上节探讨了批量新增数据,这节探讨批量更新数据两种写法的效率问题. 实现方式有两种, 一种用for循环通过循环传过来的参数集合,循环出N条sql, 另一种 用mysql的case when 条件判断变相的进行批量更新 下面进行实现. 注意第一种方法要想成功,需要在db链接url后面带一个参数  &allowMultiQueries=true 即:  jdbc:mysql://localhost:3306/mysqlTest?characterEncoding=utf-8&allowMulti

  • Oracle + Mybatis实现批量插入、更新和删除示例代码

    前言 Mybatis是web工程开发中非常常用的数据持久化的框架,通过该框架,我们非常容易的进行数据库的增删改查.数据库连接进行事务提交的时候,需要耗费的资源比较多,如果需要插入更新的数据比较多,而且每次事务只提交一条数据,会造成非常大的数据库资源浪费,导致数据库性能.系统性能大幅度下降. 关于mybatis的批量插入,网上的多数示例多半是关于MySQL数据库的,关于Oracle数据库的例子比较少.本文将给大家介绍关于Oracle+Mybatis批量插入.更新和删除的相关内容,下面话不多说了,来

  • Thinkphp批量更新数据的方法汇总

    以下小编给大家列出了三种实现thinkphp批量更新数据的方法,写的不好还请见谅,有意见欢迎提出,共同学习进步! 方法一: //批量修改 data二维数组 field关键字段 参考ci 批量修改函数 传参方式 function batch_update($table_name='',$data=array(),$field=''){ if(!$table_name||!$data||!$field){ return false; }else{ $sql='UPDATE '.$table_name

  • SqlCommandBuilder如何实现批量更新

    一般是这样的,如果用设计器将SqlDataAdapter拖到页面中使用时,不会出现SqlDataAdapter.Update(ds)更新时出错情况,因为系统会自动生成SqlDataAdapter的属性命令,比如: .UpdateCommane insertCommand selectCommand等.  但是有些程序员不喜欢用设计器,或者是有些地方没必要拖动SqlDataAdapter这么个庞大物来实现,那么SqlDataAdapter就不会自动生成相关的查询或更新语句了. 所以当执行到SqlD

  • 在ASP.NET 2.0中操作数据之三十七:DataList批量更新

    导言 在前面我们学习了如何创建item级的DataList.和可编辑的GridView一样,每个DataList里的item都包含一个Edit button,当点击时,item会变的可编辑.item级的编辑在偶尔需要更新时没什么问题,但是在有些情况下用户需要编辑大量的记录.如果一个用户需要编辑许多记录,他会被迫去不停的去点击Edit,作出修改,然后点击Update,这些大量的点击会妨碍他的工作效率.在这样的情况下,一个好的选择是提供一个完全可编辑的DataList,它的所有的item都处于编辑模

  • 在ASP.NET 2.0中操作数据之六十二:GridView批量更新数据

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

随机推荐