当我们使用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更加简短有效!
分享到:
相关推荐
本文将讨论使用 Hibernate 批量更新大量数据的方法和技巧。 批量更新的必要性 在实际应用中,我们经常需要将大量数据插入到数据库中,例如数据迁移、数据同步、数据备份等场景。在这些场景中,如果使用传统的 ...
在Java开发中,尤其是涉及到大数据量的处理时,人们往往会质疑ORM框架,如Hibernate,是否适合进行批量数据操作。然而,实际上,通过适当的技术手段,我们可以有效地解决Hibernate在批量处理时可能出现的性能问题。...
然而,在处理大量数据时,如何有效地进行批量更新和批量删除操作,是每一个开发者都可能遇到的挑战。本文将深入探讨在Hibernate中处理批量更新和批量删除的策略,以及如何优化这些操作,以提高数据库操作的效率。 #...
批量更新是指对数据库中的多条记录进行一次性更新操作,相较于单条记录更新,批量更新能够显著提高数据处理效率,减少网络通信和数据库资源消耗。在Hibernate中,默认情况下,每个实体的修改都会触发一次数据库更新...
Hibernate 下数据批量处理 Java 教程 本文主要介绍了使用 Hibernate 实现数据批量处理的方法...本文介绍了使用 Hibernate 实现数据批量处理的方法和注意事项,旨在帮助开发者更好地使用 Hibernate 实现数据批量处理。
标题"浅析Hibernate下数据批量处理方法"和描述中提到,早期的Hibernate在批量插入时可能存在效率问题,但最新版本已经进行了优化,例如通过设置`batch_size`参数来提高批量处理的性能。`batch_size`设置的是JDBC...
本文将详细介绍如何在使用JSP和Hibernate环境下进行高效的批量更新与删除操作。 ### 批量更新与批量删除 批量操作指的是在数据库层面一次性对大量数据进行更新或删除。与单条记录的更新或删除相比,批量操作能大幅...
因此,本文将详细介绍Hibernate如何高效地进行批量数据处理,包括批量插入、批量更新和批量删除。 #### 二、批量插入 在批量插入数据时,直接使用循环逐一保存的方式容易导致内存溢出。这是因为Hibernate的Session...
本篇文章将详细探讨如何利用JSF与Hibernate相结合来实现批量删除功能,以及在CRUD(创建、读取、更新和删除)操作中的应用。 首先,我们需要理解JSF的工作原理。JSF是一个基于组件的MVC(Model-View-Controller)...
在Java开发中,处理大量数据时,经常需要执行批量操作,如批量更新或批量删除。这些操作对于提高应用程序性能至关重要,尤其是在涉及成千上万条记录的情况下。Hibernate作为一款流行的Java持久层框架,支持通过其...
Struts2的Action接收到这些ID后,会调用Spring管理的Service层,Service层再通过Hibernate的Session进行数据库操作。如果所有记录都成功删除,事务会提交;如果有任何错误,事务会被回滚,防止数据不一致。 至于...
本文件主要探讨了如何使用Hibernate进行批量更新和批量删除处理,这些操作在处理大量数据时尤其重要,因为它们可以显著提高应用的性能。下面我们将深入解析这两个主题。 批量更新在Hibernate中通常涉及在一个事务中...
- **通过HQL进行批量操作**:可以使用HQL(Hibernate Query Language)编写批量操作的查询,例如更新或删除大量记录。 - **直接使用JDBC API**:如果需要更底层的控制,可以直接使用JDBC API进行批量操作。 #### 四...
例如,使用HQL的`createQuery()`方法,配合`setParameters()`方法设置参数,然后调用`executeUpdate()`进行批量更新。 批量删除则可以通过`Session.createCriteria()`创建Criteria,设定相应的限制条件,然后调用`...
Hibernate通过实体类与数据库表进行映射,实体类的对象代表了数据库中的记录。数据加载是指从数据库中获取这些对象的过程。主要有以下几种方式: 1. **懒加载(Lazy Loading)**:默认情况下,Hibernate采用懒加载...
10. **批量插入**:对于大量数据插入,可使用SQL的批处理或Hibernate的批处理功能,如Session的batch_size配置,提高性能。 在实际开发中,我们还需要注意一些优化技巧,比如懒加载(@OneToMany、@ManyToOne等关系...
Hibernate 是一款 ORM 框架(对象关系映射),它对 JDBC(数据库连接技术的简称)进行了轻量级的封装,使得 Java 程序员可以随心所欲的使用面向对象的编程思想来操作数据库。Hibernate 的作用:用面向对象的编程思想...
Hibernate配置各种数据源 <hibernate-configuration> <!– 各属性的配置–> <!—为true表示将Hibernate发送给数据库的sql显示出来 –> ...– 设定对数据库进行批量删除 –> ”jdbc.batch_size”>30</property>
4. **批量处理与Session管理**:使用Hibernate API进行批量处理时,可以通过限制每次处理的数据量来优化。例如,每处理一定数量的对象后,立即调用`session.flush()`和`session.evict()`。这样可以将内存中的对象...