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

在Hibernate应用中实现批量操作

阅读更多
在Hibernate应用中实现批量操作
最近的一个项目中,作一个查询的时候需求批量更新一下数据,然后在查询。
在Hiberante应用中,这个更新操作

一、session.update(object)
一个方法是,根据条件加载出一个list,如果符合条件的有上万或更多,会加载这么多个对象到sessin缓存中
然后遍历,对每个对象挨个更新。当事务提交是会清理缓存,同时执行上万个update语句
tx = session.beginTransaction();
Iterator objects =session.find("from Project where p.id>0").iterator();
while(objects .hasNext()){
Object object=(Object)objects .next();
object.setXXX();
} 
tx.commit();
session.close();

以上批量更新方式有两个缺点:
(1) 占用大量内存,必须把所有符合条件的对象先加载到内存,然后一一更新它们。
(2) 执行的update语句的数目太多,每个update语句只能更新一个Customer对象,频繁的访问数据库,会降低应用的性能。
为了迅速释放对象占用的内存,可以在更新每个对象后,就调用Session的evict()方法立即释放它的内存:
tx = session.beginTransaction();
Iterator objects=session.find(“hql").iterator();
while(objects.hasNext()){
Object  object =(Object) objects.next();
object.setXXX();
session.flush();
session.evict(customer);
} 
tx.commit();
session.close();

flush()方法使Hibernate立刻根据这个object对象的状态变化同步更新数据库,从而立即执行相关的update语句;evict()方法用于把这个object对象从缓存中清除出去,从而及时释放它占用的内存。
可以稍微提高一些性能,但还是要产生上万个update语句,这个影响批量操作的重要因素。

二、直接执行sql
如果hibernate能执行执行一个update语句,那么符合条件的对象将一次性更新好。
但是Hibernate并没有直接提供执行这种update语句的接口。应用程序必须绕过Hibernate API,直接通过JDBC API来执行该SQL语句:
tx = session.beginTransaction();
Connection con=session.connection();
PreparedStatement stmt=con.prepareStatement(sql");
stmt.executeUpdate();
tx.commit();

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

三、使用存储过程
如果底层数据库(如Oracle)支持存储过程,也可以通过存储过程来执行批量更新。存储过程直接在数据库中运行,速度更加快。
create or replace procedure updateProject is
begin
  update project p set p.total_intend_gather = 
  (select sum(ig.gather_sum) from intend_gather ig where ig.project_number=p.project_number);
  
  update project p set p.total_actual_gather = 
  (select sum(ag.gahter_sum) from actual_gather ag where ag.project_number=p.project_number);
  
  update project p set p.total_invoice=
(select sum(invoice.invoice_sum) from invoice invoice
 where invoice.intend_id in
 (select ig.intend_id  from intend_gather ig where ig.project_number=p.project_number));
 
end updateProject;


调用代码
        Session session = this.getSession();
        Transaction tx =null;
        try {
            tx = session.beginTransaction();
            Connection con = session.connection();
            String procedure = "{call updateproject() }";
            CallableStatement cstmt = con.prepareCall(procedure);
            cstmt.executeUpdate();
            tx.commit();

        } catch (Exception e) {
           tx.rollback();
        }


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

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

能够实现批量删除,但是令人失望的是Session的delete()方法并没有执行以下delete语句
delete from PROJECT where ID>0;

而是
Session的delete()方法先通过以下select语句把所有符合的对象加载到内存中:
select * from Project where ID>0;

接下来执行N多个delete语句,逐个删除project对象:
delete from PROJECT where ID=i;
delete from PROJECT where ID=j;
delete from PROJECT where ID=k;


所以,直接通过Hibernate API进行批量更新和批量删除都不爽。而直接通过JDBC API执行相关的SQL语句或调用相关的存储过程,是批量更新和批量删除的最佳方式,这两种方式都有以下优点:
(1) 无需把数据库中的大批量数据先加载到内存中,然后逐个更新或修改它们,因此不会消耗大量内存。
(2) 能在一条SQL语句中更新或删除大批量的数据。
分享到:
评论

相关推荐

    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. ...

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

    1. 基于Struts2框架和Hibernate框架进行编程设计,连接MySQL数据库实现数据的增删查改,应用Jsp、HTML、CSS、JavaScript对访问页面进行编写和美化。 2. 分别创建book表和user表,用以存放图书信息和用户数据。其中...

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

     10.1.2 Hibernate应用程序中的事务   10.1.3 使用Java Persistence的事务   10.2 控制并发访问   10.2.1 理解数据库级并发   10.2.2 乐观并发控制   10.2.3 获得额外的隔离性保证   10.3 非事务数据...

    让hibernate输出sql语句参数配置.doc

    Hibernate 配置参数详解 Hibernate 是一个流行的 ORM(Object-Relational Mapping)框架,广泛应用于 Java 企业应用开发...通过合理配置这些参数,可以提高 Hibernate 框架下的对象效率,从而实现对 J2EE 应用的优化。

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

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

    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 参考文档

    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: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持久化类映射到...

    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版).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. 映射...

    Hibernate教程

    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 2.2.2...

    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. 配置 ...

    ssh(structs,spring,hibernate)框架中的上传下载

    这是Hibernate3引入的新特性,对于包含重量级大数据的表字段,这种抽取方式提高了对大字段操作的灵活性,否则加载Tfile对象的结果集时如果总是返回fileContent,这种批量的数据抽取将可以引起数据库的"洪泛效应"。...

    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. ...

Global site tag (gtag.js) - Google Analytics