`
newleague
  • 浏览: 1472263 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

Hibernate批量更新和批量删除实战

阅读更多
    Hibernate批量更新是指在一个事务中更新大批量数据,Hibernate批量删除是指在一个事务中删除大批量数据。以下程序直接通过Hibernate API批量更新CUSTOMERS表中年龄大于零的所有记录的AGE字段:

     

    本文向大家介绍Hibernate批量更新和Hibernate批量删除,可能好多人还不了解Hibernate批量更新和Hibernate批量删除,没有关系,看完本文你肯定有不少收获,希望本文能教会你更多东西。

    Hibernate批量更新是指在一个事务中更新大批量数据,Hibernate批量删除是指在一个事务中删除大批量数据。以下程序直接通过Hibernate API批量更新CUSTOMERS表中年龄大于零的所有记录的AGE字段:

    1. tx = session.beginTransaction();    
    2. Iterator customers=session.find("from Customer c where c.age>0").iterator();    
    3. while(customers.hasNext()){    
    4. Customer customer=(Customer)customers.next();    
    5. customer.setAge(customer.getAge()+1);    
    6. }     
    7. tx.commit();    
    8. session.close();  

    如果CUSTOMERS表中有1万条年龄大于零的记

    
    

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

    1.  
      1. update CUSTOMERS set AGE=? …. where ID=i;    
      2. update CUSTOMERS set AGE=? …. where ID=j;    
      3. update CUSTOMERS set AGE=? …. where ID=k;  
    
    

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

    (1) 占用大量内存,必须把1万个Customer对象先加载到内存,然后一一更新它们。
    (2) 执行的update语句的数目太多,每个update语句只能更新一个Customer对象,必须通过1万条update语句才能更新一万个Customer对象,频繁的访问数据库,会大大降低应用的性能。

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

      1. tx = session.beginTransaction();    
      2. Iterator customers=session.find("from Customer c where c.age>0").iterator();    
      3. while(customers.hasNext()){    
      4. Customer customer=(Customer)customers.next();    
      5. customer.setAge(customer.getAge()+1);    
      6. session.flush();    
      7. session.evict(customer);    
      8. }     
      9. tx.commit();    
      10. session.close();  

       

      
      

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

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

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

      那么以上一条update语句就能更新CUSTOMERS表中的1万条记录。但是Hibernate并没有直接提供执行这种update语句的接口。应用程序必须绕过Hibernate API,直接通过JDBC API来执行该SQL语句:

        1. tx = session.beginTransaction();    
        2. Connection con=session.connection();    
        3. PreparedStatement stmt=con.prepareStatement("update CUSTOMERS set AGEAGE=AGE+1 "    
        4. +"where AGE>0 ");    
        5. stmt.executeUpdate();    
        6. tx.commit();  

         

        
        

        以上程序演示了绕过Hibernate API,直接通过JDBC API访问数据库的过程。应用程序通过Session的connection()方法获得该Session使用的数据库连接,然后通过它创建PreparedStatement对象并执行SQL语句。值得注意的是,应用程序仍然通过Hibernate的Transaction接口来声明事务边界。
        如果底层数据库(如Oracle)支持存储过程,也可以通过存储过程来执行Hibernate批量更新。存储过程直接在数据库中运行,速度更加快。在Oracle数据库中可以定义一个名为batchUpdateCustomer()的存储过程,代码如下:

        1.  
          1. create or replace procedure batchUpdateCustomer(p_age in number) as    
          2. begin    
          3. update CUSTOMERS set AGEAGE=AGE+1 where AGE>p_age;    
          4. end;  
        
        

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

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

           

          
          

          从上面程序看出,应用程序也必须绕过Hibernate API,直接通过JDBC API来调用存储过程。
          Session的各种重载形式的update()方法都一次只能更新一个对象,而delete()方法的有些重载形式允许以HQL语句作为参数,例如:

          1. session.delete("from Customer c where c.age>0");  

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

          1. delete from CUSTOMERS where AGE>0;  

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

          1. select * from CUSTOMERS where AGE>0;  

          接下来执行一万条delete语句,逐个删除Customer对象:

          1. delete from CUSTOMERS where ID=i;    
          2. delete from CUSTOMERS where ID=j;    
          3. delete from CUSTOMERS where ID=k;  

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

          (1) 无需把数据库中的大批量数据先加载到内存中,然后逐个更新或修改它们,因此不会消耗大量内存。
          (2) 能在一条SQL语句中更新或删除大批量的数据。

          分享到:
          评论

          相关推荐

            Hibernate实战(第2版 中文高清版)

            第一部分 从Hibernate和EJB 3.0开始  第1章 理解对象/关系持久化   1.1 什么是持久化   1.1.1 关系数据库   1.1.2 理解SQL   1.1.3 在Java中使用SQL   1.1.4 面向对象应用程序中的持久化   1.2 范式不...

            《深入浅出MyBatis技术原理与实战》高清完整PDF下载

            为了增加实用性,作者还介绍了MyBatis-Spring项目,使得读者能够学习到如何把MyBatis整合到Spring项目中,最后作者还将讲解一些常用实例,比如Blob字段、文件上传、批量、动态表名等实用场景,让读者能够参考和注意...

            经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

            中文名: 经典Java EE企业应用实战--基于WebLogic/JBoss的...11.4 批量更新和批量删除 478 11.4.1 批量更新 479 11.4.2 批量删除 480 11.5 原生SQL查询 481 11.5.1 使用原生SQL查询 481 11.5.2 结果集映射和实体查询 482...

            (高清+目录)深入浅出MyBatis技术原理与实战.zip

            为了增加实用性,作者还介绍了MyBatis-Spring项目,使得读者能够学习到如何把MyBatis整合到Spring项目中,最后作者还将讲解一些常用实例,比如Blob字段、文件上传、批量、动态表名等实用场景,让读者能够参考和注意...

            Spring3.x企业应用开发实战(完整版) part1

            11.2.3 批量更改数据 11.2.4 查询数据 11.2.5 查询单值数据 11.2.6 调用存储过程 11.3 BLOB/CLOB类型数据的操作 11.3.1 如何获取本地数据连接 11.3.2 相关的操作接口 11.3.3 插入Lob类型的数据 11.3.4 以块数据方式...

            Spring.3.x企业应用开发实战(完整版).part2

            11.2.3 批量更改数据 11.2.4 查询数据 11.2.5 查询单值数据 11.2.6 调用存储过程 11.3 BLOB/CLOB类型数据的操作 11.3.1 如何获取本地数据连接 11.3.2 相关的操作接口 11.3.3 插入Lob类型的数据 11.3.4 以块数据方式...

            iBATIS实战

            5.3 更新和删除数据 88 5.3.1 处理并发更新 88 5.3.2 更新或删除子记录 89 5.4 运行批量更新 90 5.5 使用存储过程 91 5.5.1 优缺点分析 92 5.5.2 IN、OUT和INOUT参数 93 5.6 小结 95 第6章 使用高级查询技术 96 6.1...

            Java Web程序设计教程

            14.2spring和hibernate的整合 279 14.2.1spring对hibernate的支持 279 14.2.2管理sessionfactory 279 14.2.3hibernate的dao实现 281 14.2.4使用hibernatetemplate 281 14.2.5管理hibernate事务 282 14.3项目...

            最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

            │ Java面试题56.ibatis和hibernate有什么不同.mp4 │ Java面试题57.hibernate对象状态及其转换.mp4 │ Java面试题58:hibernate的缓存.mp4 │ Java面试题59.webservice的使用场景.mp4 │ Java面试题60.Activiti的...

          Global site tag (gtag.js) - Google Analytics