`
一日一博
  • 浏览: 229916 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Hibernate4性能之批量处理的三种方式

阅读更多
假如有如下程序,需要向数据库里面加如100000条数据
Session session = sessionFactory.openSession();  
Transaction tx = session.beginTransaction();  
for ( int i=0; i<100000; i++ ) {  
    Customer customer = new Customer(.....);  
    session.save(customer);
}  
tx.commit();  
session.close();  

这段程序大概运行到50000条记录左右会失败并抛出内存溢出异常(OutOfMemoryException),按照前面讲过的原理,新产生的object瞬时对象变为持久对象后,在session关闭之前将自动装载到session级别的缓存区,如果,程序使用了二级缓存,同样也会装入到二级缓存。所以当数据量大时,导致内存溢出。

解决方案:
设置批量抓取数量参数设置到一个合适值(比如10-50之间),同时最好关闭二级缓存,如果有的话。

<property name="hibernate.jdbc.batch_size">20</property>
<property name="hibernate.cache.use_second_level_cache">false</property>

但是,这不是绝对必须的,因为我们可以显式设置CacheMode来关闭与二级缓存的交互。
如果要将很多对象持久化,你必须通过经常的调用 flush() 以及稍后调用 clear() 来控制第一级缓存的大小。

Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
//将本批数据插入数据库,并释放内存
for ( int i=0; i<100000; i++ ) {  
   Customer customer = new Customer();  
   session.save(customer);  
   if ( i % 20 == 0 ) { //20, same as the JDBC batch size
      session.flush();  
      session.clear();  
   }  
}
tx.commit();
session.close();



Hibernate批量操作的三种方法:

方法一(直接用HQL语句):
由Query.executeUpdate()方法返回的整型值表明了受此操作影响的记录数量。注意这个数值可能与数据库中被(最后一条SQL语句)影响了的“行”数有关,也可能没有。一个大批量HQL操作可能导致多条实际的SQL语句被执行, 举个例子,对joined-subclass映射方式的类进行的此类操作。这个返回值代表了实际被语句影响了的记录数量。在那个joined-subclass的例子中, 对一个子类的删除实际上可能不仅仅会删除子类映射到的表而且会影响“根”表,还有可能影响与之有继承关系的joined-subclass映射方式的子类的表。

INSERT语句的伪码是: INSERT INTO EntityName properties_list select_statement.
要注意的是:只支持INSERT INTO ... SELECT ...形式,不支持INSERT INTO ... VALUES ...形式.

    Session session=SessionFactory.openSession();
    Transaction tx=session.beginTransaction();
    String hql = "update Customer set phone=Trim(phone)",
    //String hql = "delete Customer where id < 5000",
    //String hql = "insert into DelinquentAccount (id, name) select c.id, c.name from Customer c where ...";
    int createdEntities = s.createQuery(hql).executeUpdate();
    tx.commit();
    session.close();



方法二(利用服务器游标):
此方法同样适用于检索和更新数据。此外,在进行会返回很多行数据的查询时, 你需要使用 scroll()方法以便充分利用服务器端游标所带来的好处。

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
//关掉缓存策略
ScrollableResults customers = session.getNamedQuery("GetCustomers")
                              .scroll(ScrollMode.FORWARD_ONLY)
                              .setCacheMode(CacheMode.IGNORE);
while ( customers.next() ) {  
   Customer customer = (Customer) customers.get(0);  
   customer.updateStuff(...);  
   session.update(customer);
} 
tx.commit();
session.close(); 



方法三(无状态session接口):
StatelessSession没有持久化上下文,也不提供多少高层的生命周期语义。特别是,无状态session不实现第一级cache,也不和第二级缓存,或者查询缓存交互。它不实现事务化写,也不实现脏数据检查。用stateless session进行的操作甚至不级联到关联实例。stateless session忽略集合类(Collections)。通过stateless session进行的操作不触发Hibernate的事件模型和拦截器。无状态session对数据的混淆现象免疫,因为它没有第一级缓存。无状态session是低层的抽象,和低层JDBC相当接近。

在下面的例子中,查询返回的Customer实例立即被脱管(detach)。它们与任何持久化上下文都没有关系。
StatelessSession 接口定义的insert(),update()和delete()操作是直接的数据库行级别操作,其结果是立刻执行一条INSERT, UPDATE 或 DELETE 语句。因此,它们的语义和Session 接口定义的save(),saveOrUpdate()和delete()操作有很大的不同。
StatelessSession不参与hibernate的各种缓存,默认的隔离级别对他也不起作用,直接生成sql直接执行,类似jdbc。但是他需要自己去写事务提交,spring好像也拦截不到它
如果batch设置成100的话,那么会每一百次执行一次同步一次数据库
有一个注意的地方:如果表中的主键是identity的话,那么batch就会失效,直接用jdbc也是一样失效

StatelessSession session = sessionFactory.openStatelessSession();  
Transaction tx = session.beginTransaction();
ScrollableResults customers = session.getNamedQuery("GetCustomers")
                              .scroll(ScrollMode.FORWARD_ONLY);
while ( customers.next() ) {  
   Customer customer = (Customer) customers.get(0);  
   customer.updateStuff(...);  
   session.update(customer);  
} 
tx.commit();
session.close(); 
分享到:
评论
1 楼 丛林黑豹 2013-02-04  
hibernate海量数据操作在实际中不会这样用。一般设置参数后,A对象的N个实例,打入B对象的collection,attachdirty方法实现B对A的批量操作。其数据管理完全交给hibernate,至于hibernate的管理策略是什么?靠你分析具体业务应用设计。

相关推荐

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

    然而,实际上,通过适当的技术手段,我们可以有效地解决Hibernate在批量处理时可能出现的性能问题。以下是一些关于如何在Hibernate环境下优化批量数据处理的策略。 首先,了解问题的根源。在上述例子中,当尝试向...

    在Hibernate应用中处理批量更新和批量删除

    #### 策略一:利用Hibernate的批量处理机制 1. **使用`flush()`和`evict()`方法**:在修改实体后,主动调用`session.flush()`方法,使Hibernate将缓存中的变更同步到数据库,然后调用`session.evict(entity)`方法,...

    Hibernate批量处理

    批量处理是提高Hibernate应用性能的重要手段之一。通过合理选择批量处理方式、调整相关配置参数以及优化内存管理,可以显著提升系统的整体性能。希望本文能帮助开发者更好地理解和应用Hibernate中的批量处理技术。

    在Hibernate中处理批量更新和批量删除

    在Hibernate中,最直观的批量更新方式是通过循环遍历查询结果集,并对每个实体进行更新,然后提交事务。例如: ```java Transaction tx = session.beginTransaction(); Iterator&lt;Customer&gt; customers = session....

    hibernate批量删除

    为了解决这一问题,Hibernate提供了对JDBC的支持,使得开发者能够利用JDBC的批量处理能力来优化批量删除操作。 #### 实现方式一:使用Hibernate API 原始的实现方式是直接通过Hibernate API来执行批量删除操作,...

    Hibernate批量处理数据

    批量处理数据是提高应用性能的关键之一,特别是在大数据量的情况下。通过对Hibernate的合理配置以及采取合适的批量处理策略,可以有效提升系统的整体性能,避免内存溢出等问题的发生。希望本文提供的方法能帮助...

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

    总的来说,虽然Hibernate在批量处理上可能不如JDBC直接操作数据库高效,但通过合理设置参数和使用特定的处理方式,如批处理大小、滚动结果集和适时清理缓存,可以在一定程度上改善性能。在实际项目中,需要根据具体...

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

    Hibernate 下数据批量处理 Java 教程 本文主要介绍了使用 Hibernate 实现数据批量处理的方法和注意事项。在 Java 中,对数据批量处理的需求非常重要,但许多人对 Java 是否适合批量处理持有怀疑念头。实际上,如果...

    Hibernate中大量数据的更新

    Hibernate 提供了两种批量更新机制:一级缓存(First-Level Cache)和批量抓取(Batching)。 一级缓存 Hibernate 的一级缓存是指 Session 对象中缓存的所有对象。在批量更新时,如果不及时清除一级缓存,可能会...

    struts2 hibernate spring 整合批量删除源码

    总的来说,这个批量删除源码示例展示了如何利用Struts2处理HTTP请求,Spring管理依赖,以及Hibernate与数据库交互,是学习和理解三大框架整合开发的一个实践案例。通过分析和理解这段代码,开发者可以提升自己在企业...

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

    本文件主要探讨了如何使用Hibernate进行批量更新和批量删除处理,这些操作在处理大量数据时尤其重要,因为它们可以显著提高应用的性能。下面我们将深入解析这两个主题。 批量更新在Hibernate中通常涉及在一个事务中...

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

    在当今的IT开发领域中,特别是在使用Java语言开发的Web应用程序中,JSP和Hibernate是构建动态网站和Web服务时经常使用的两种技术。...开发者应当根据具体的应用场景和数据库特性,选择合适的批量处理策略。

    hibernate性能优化方案

    2. **Fetch Size和Batch Size**:这两个参数分别控制了每次从数据库读取的数据量和批量处理的数据量,合理设置可以提高效率。 3. **关闭SQL语句打印**:在生产环境中,关闭Hibernate的日志输出可以减少不必要的I/O...

    java私塾独家首发最新Hibernate4教程

    - **批量处理**:提高数据处理效率,例如批量插入、更新等操作。 - **过滤器**:提供细粒度的数据访问控制。 #### 三、关系映射与事务管理 **3.1 关系映射** - **集合映射**:一个实体类与多个实例的关联。 - **...

    hibernate性能:性能、规模、风险 初评

    3. **批量处理**:Hibernate支持批量更新、批量插入等操作,这些批量操作可以显著减少与数据库的交互次数,提高执行效率。 4. **查询优化**:Hibernate提供多种查询方式,如HQL(Hibernate Query Language)、...

    优化Hibernate性能的几点建议

    ### 优化Hibernate性能的几点建议 #### 一、概述 Hibernate作为Java开发中非常流行的ORM(对象关系映射)框架之一,在实现Java对象与数据库之间的转换方面发挥了重要作用。然而,在实际应用过程中,为了提高系统的...

    java数据批量处理

    在Java编程领域,数据批量处理是一项常见的任务,尤其在大数据、数据库操作以及系统集成等场景中,批量处理能显著提高效率并减少资源消耗。本文将深入探讨Java如何进行数据批量处理,涉及的主要知识点包括批量读取、...

    hibernate4 jar包

    7. 支持批量操作:Hibernate4支持批处理,比如批量插入、更新和删除,这在处理大量数据时非常有用。 8. 异步操作:Hibernate4可以通过集成JPA(Java Persistence API)的批处理和多线程特性实现异步操作,提升系统...

    Hibernate 性能优化

    然而,对于初次接触 Hibernate 的开发者来说,可能会遇到性能方面的问题,尤其是在与传统的 JDBC 方式相比时。这些问题如果不加以解决,很容易影响到项目的整体进度。本文将详细介绍如何优化 Hibernate 的性能,并...

Global site tag (gtag.js) - Google Analytics