`
leogao_emcom
  • 浏览: 81001 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

使用Hibernate进行数据的批量更新

阅读更多
当我们使用SQL直接在数据库里面操作是,批量更新一大批数据是很快捷的,比如
update Companys set BidPrice='1000' where Name='MS'
不管有多少条Name='MS'的记录都会被更新,而且直接作用于数据至少比较快。
但是当我们使用Hibernate的时候,事情就有点变化了,当我们必须批处理如以上的数据时,假定有10000条,那么我们必须先Query(..).List出10000个Company对象,而这些对象会马上加载到Hibernate的第一级缓存中,也就是Session缓存,成为持久化对象(PO),
在更新他们的时候:
 
  Iterator Compamys=session.createQuery("from Company where Name='MS'").list().iterator();
  while(Companys.hasNext())
  {
      Company comany=(Company)Companys.next();
      company.setBidPrice(1000);
  }
  tx.commit();
  Session.close();
  

  加载大量的PO会消耗很多内存,更加可怕的是,在加载PO的时候,Hibernate会产生数据的快照以便用来生成最终的SQL语句,当commit的时候,就会根据快照和实际PO的属性值进行比较,一旦发现有变化的属性,就会生成一个SQL语句,换句话说上面这点代码不仅要占用10000个Company对象的内存,还要生成10000个SQL语句。
  所以有人想出限制批量的数量,把Hibernate缓存限制到一个数量,比如20,也就是说缓存中只能存在20个PO,然后在上面的代码中加计数,一旦遍历的数量达到20,就Flush,这里就不贴出代码了,我想说明的是这样的方式是治标不治本,还是会产生20个SQL语句,另外10000个PO对象,只是分批次(每批20个)载入缓存和分批次产生20个SQL,一共500批,客户机的负载是小了,但是数据库方面让然不容乐观,另外就是网络通信还是10000次,这是一个很笨的做法。
   另外如果有人开启了第二级缓存,那好,Hibernate会把在第一级缓存做的事情再做一次,结果重新发生了10000次更新操作,也就是总共20000次的操作。
    有人想用StatelessSession来执行批量更新,因为至少PO不会进入缓存,都是游离状态的对象了,也就不会占用缓存,由于没有被缓存引用,那么只要这个游离的PO被引用=0,就会被JVM垃圾收集掉,至少很大部分不用占用了,但是也许问题更大,因为在确认一个属性是否跟新过了而产生一个对应的SQL前必须先查询数据库,因为这些对象都是游离对象,没有快照支持,所以必须在更新之前查询一下数据库,也就是说每更新一次就得查询一次,这下好了,如果批量跟新10000个,也就必须查询10000次,数据库的压力上来了!也是不太好的办法。
     估计有人还会想出来,直接JDBC吧,那么我们就是失去了使用Hibernate的机会,也就享受不到它提供的各种优于直接使用JDBC的好处,另外在结构上就成了混合型,结构不整洁了。
      那怎么办?其实直接用HQL就可以:
     
       String hqlStatement="update Company m set m.BiDPrice=:NewPrice where m.Name=:ComName";
       int updatedEntities=session.createQuery(hqlStatement)
           .setString("NewPrice","1000")
           .setString("ComName","MS")
           .executeUpdate();
        tx.commit();
        session.close();
     

     它不需要缓存,另外只生成一条SQL update语句,客户机内存和服务器的负载都很低,就和直接使用SQL一样,但是还是有些性能损失的,至少Hibernate必须根据方言把上面的HQL转换成能够执行的SQL,需要一定的CPU时间。但是这样少的损失是可以忍受的,毕竟就是一次计算的过程,即使二级缓存被打开,也不会产生什么副作用了。
      但是也不并是说任何场合下使用HQL都很高效,比如取得一个Company对应的所有订单,如果用HQL就会马上为所有这些订单对象填充数据,如果用Company.getOrders()就会好的多,因为我们可以在hbm映射文件中将Company的lazy=true,这样就有了延迟加载的能力,也就是说,我们在调用Company,getOrders才开始加载数据,不用的时候不加载。
      其实,批量更新,如果用Hibernate调用存储过程,就更加快捷,网络交通只是一存储过程的名称和参数,比写一个HQL更加简短有效!
      
0
0
分享到:
评论
1 楼 liangguanhui 2010-11-03  
有一次去一个公司笔试的时候,有一道题目是关于HQL可以干啥,当时选了Query,后来才发现原来可以可以跟普通SQL一样DML。当然,一级缓存就失去了对这些对象的控制了。

相关推荐

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

    很多人都对Java在批量数据的处理方面是否是其合适的场所持有怀疑的念头,由此延伸,...下面以Hibernate为例来做为说明,假如我们真的不得不在Java中使用Hibernate来对数据进行批量处理的话。 向数据库插入100 000条数据

    Hibernate中大量数据的更新

    使用Hibernate将大量记录插入到数据库

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

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

    hibernate批量删除

    在我们的Java项目中,批量更新是指在一个事务中更新大批量数据,批量删除是指在一个事务中删除大批量数据。批量删除虽然在Hibernate里也可以实现,但...其实Hibernate提供的JDBC接口,可以方便的进行批量的更新和删除。

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

    批量更新是指在一个事务中更新大批量数据,批量删除是指在一个事务中删除大批量数据。

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

    不建议用Hibernate,它的insert效率实在不搞,不过最新版本的Hibernate似乎已经在批量处理的时候做过优化了,设置一些参数如batch_size,不过性能我没有测试过

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

    主要介绍了Hibernate实现批量添加数据的方法,详细分析了基于Hibernate执行批量添加操作的具体步骤与相关实现代码,需要的朋友可以参考下

    Hibernate配置各种数据源详解

    Hibernate配置各种数据源 <hibernate-configuration> <!– 各属性的配置–> <!—为true表示将Hibernate发送给数据库的sql显示出来 –> ...– 设定对数据库进行批量删除 –> ”jdbc.batch_size”>30</property>

    Hibernate批量处理数据

    看完该文件你就可以最高效率的批量处理数据

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

    主要介绍了Hibernate批量处理海量数据的方法,较为详细的分析了Hibernate批量处理海量数据的原理与相关实现技巧,需要的朋友可以参考下

    Java中Hibernate的批量插入

    Hibernate完全以面向对象的方式来操作数据库,当程序里以面向对象的方式操作持久化对象时,将被自动转换为对数据库的操作。...为了面对这种批量处理的场景,Hibernate提供了批量处理的解决方案。下面分别

    Hibernate批量处理

    高效的进行批量数据的处理方案,留作参考。

    Hibernate管理Session和批量操作分析

    主要介绍了Hibernate管理Session和批量操作的技巧,包括Hibernate管理Session、批量处理数据等的常用技巧及注意事项,具有一定的参考借鉴价值,需要的朋友可以参考下

    Hibernate

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

    Hibernate+中文文档

    3.2. Hibernate数据源属性 3.3. Hibernate配置属性 3.4. Hibernate JDBC和连接(connection)属性 3.5. Hibernate缓存属性 3.6. Hibernate事务属性 3.7. 其他属性 3.8. Hibernate SQL方言 (hibernate.dialect) ...

    hibernate基础教程

    在Hibernate中使用两极缓存结构,第一级缓存是Session级别的缓存,Session级别的缓存是由Hibernate管理的,一般情况下无需进行干预.第二级缓存是 SessionFactory级别的缓存,SessionFactory级的缓存可以进行配置和...

    彻底解决hibernate常见难点.zip

    Hibernate处理1-N关系时保存技巧、Hibernate缓存机制、Hibernate批量处理数据、Hibernate三种继承映射策略、hibernate映射体系、Hibernate主键生成策略、持久层DAO设计建议、基于xml文件的bean、使用HibernateAPI在...

    HibernateAPI中文版.chm

    3.2. Hibernate数据源属性 3.3. Hibernate配置属性 3.4. Hibernate JDBC和连接(connection)属性 3.5. Hibernate缓存属性 3.6. Hibernate事务属性 3.7. 其他属性 3.8. Hibernate SQL方言 (hibernate.dialect) ...

    hibernate3.2中文文档(chm格式)

    3.2. Hibernate数据源属性 3.3. Hibernate配置属性 3.4. Hibernate JDBC和连接(connection)属性 3.5. Hibernate缓存属性 3.6. Hibernate事务属性 3.7. 其他属性 3.8. Hibernate SQL方言 (hibernate.dialect) ...

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

     16.4.5 批量延迟检索和批量立即检索(使用batch-size属性)  16.5 控制迫切左外连接检索的深度  16.6 在应用程序中显式指定迫切左外连接检索策略  16.7 属性级别的检索策略  16.8 小结  16.9 思考题 第17章 ...

Global site tag (gtag.js) - Google Analytics