`
happyxuzheng
  • 浏览: 5282 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

详解如何对Hibernate进行优化的方案

阅读更多
一、批量修改和删除

  在Hibernate 2中,如果需要对任何数据进行修改和删除操作,都需要先执行查询操作,在得到要修改或者删除的数据后,再对该数据进行相应的操作处理。在数据量少的情况下采用这种处理方式没有问题,但需要处理大量数据的时候就可能存在以下的问题:

   占用大量的内存。

   需要多次执行update/delete语句,而每次执行只能处理一条数据。

  以上两个问题的出现会严重影响系统的性能。因此,在Hibernate 3中引入了用于批量更新或者删除数据的HQL语句。这样,开发人员就可以一次更新或者删除多条记录,而不用每次都一个一个地修改或者删除记录了。

  如果要删除所有的User对象(也就是User对象所对应表中的记录),则可以直接使用下面的HQL语句:

  delete User

  而在执行这个HQL语句时,需要调用Query对象的executeUpdate()方法,具体的实例如下所示:

  String HQL="delete User";

  Query query=session.createQuery(HQL);

  int size=query.executeUpdate();

  采用这种方式进行数据的修改和删除时与直接使用JDBC的方式在性能上相差无几,是推荐使用的正确方法。

  如果不能采用HQL语句进行大量数据的修改,也就是说只能使用取出再修改的方式时,也会遇到批量插入时的内存溢出问题,所以也要采用上面所提供的处理方法来进行类似的处理。

  二、 使用SQL执行批量操作

  在进行批量插入、修改和删除操作时,直接使用JDBC来执行原生态的SQL语句无疑会获得最佳的性能,这是因为在处理的过程中省略或者简化了以下处理内容:

  ● HQL语句到SQL语句的转换。

  ● Java对象的初始化。

  ● Java对象的缓存处理。

  但是在直接使用JDBC执行SQL语句时,有一个最重要的问题就是要处理缓存中的Java对象。因为通过这种底层方式对数据的修改将不能通知缓存去进行相应的更新操作,以保证缓存中的对象与数据库中的数据是一致的。

  三、 提升数据库查询的性能

  数据库查询性能的提升也是涉及到开发中的各个阶段,在开发中选用正确的查询方法无疑是最基础也最简单的。

  1 、SQL语句的优化

  使用正确的SQL语句可以在很大程度上提高系统的查询性能。获得同样数据而采用不同方式的SQL语句在性能上的差距可能是十分巨大的。

  由于Hibernate是对JDBC的封装,SQL语句的产生都是动态由Hibernate自动完成的。Hibernate产生SQL语句的方式有两种:一种是通过开发人员编写的HQL语句来生成,另一种是依据开发人员对关联对象的访问来自动生成相应的SQL语句。

  至于使用什么样的SQL语句可以获得更好的性能要依据数据库的结构以及所要获取数据的具体情况来进行处理。在确定了所要执行的SQL语句后,可以通过以下三个方面来影响Hibernate所生成的SQL语句:

   HQL语句的书写方法。

   查询时所使用的查询方法。

   对象关联时所使用的抓取策略。

  2 、使用正确的查询方法

  在前面已经介绍过,执行数据查询功能的基本方法有两种:一种是得到单个持久化对象的get()方法和load()方法,另一种是Query对象的list()方法和iterator()方法。在开发中应该依据不同的情况选用正确的方法。

  get()方法和load()方法的区别在于对二级缓存的使用上。load()方法会使用二级缓存,而get()方法在一级缓存没有找到的情况下会直接查询数据库,不会去二级缓存中查找。在使用中,对使用了二级缓存的对象进行查询时最好使用load()方法,以充分利用二级缓存来提高检索的效率。

  list()方法和iterator()方法之间的区别可以从以下几个方面来进行比较。

   执行的查询不同

  list()方法在执行时,是直接运行查询结果所需要的查询语句,而iterator()方法则是先执行得到对象ID的查询,然后再根据每个ID值去取得所要查询的对象。因此,对于list()方式的查询通常只会执行一个SQL语句,而对于iterator()方法的查询则可能需要执行N+1条SQL语句(N为结果集中的记录数)。

  iterator()方法只是可能执行N+1条数据,具体执行SQL语句的数量取决于缓存的情况以及对结果集的访问情况。

   缓存的使用

  list()方法只能使用二级缓存中的查询缓存,而无法使用二级缓存对单个对象的缓存(但是会把查询出的对象放入二级缓存中)。所以,除非重复执行相同的查询操作,否则无法利用缓存的机制来提高查询的效率。

  iterator()方法则可以充分利用二级缓存,在根据ID检索对象的时候会首先到缓存中查找,只有在找不到的情况下才会执行相应的查询语句。所以,缓存中对象的存在与否会影响到SQL语句的执行数量。

   对于结果集的处理方法不同

  list()方法会一次获得所有的结果集对象,而且它会依据查询的结果初始化所有的结果集对象。这在结果集非常大的时候必然会占据非常多的内存,甚至会造成内存溢出情况的发生。

  iterator()方法在执行时不会一次初始化所有的对象,而是根据对结果集的访问情况来初始化对象。因此在访问中可以控制缓存中对象的数量,以避免占用过多缓存,导致内存溢出情况的发生。使用iterator()方法的另外一个好处是,如果只需要结果集中的部分记录,那么没有被用到的结果对象根本不会被初始化。所以,对结果集的访问情况也是调用iterator()方法时执行数据库SQL语句多少的一个因素。

  所以,在使用Query对象执行数据查询时应该从以上几个方面去考虑使用何种方法来执行数据库的查询操作。

  四、 使用正确的抓取策略

  所谓抓取策略(fetching strategy)是指当应用程序需要利用关联关系进行对象获取的时候,Hibernate获取关联对象的策略。抓取策略可以在O/R映射的元数据中声明,也可以在特定的HQL或条件查询中声明。

  Hibernate 3定义了以下几种抓取策略。

   连接抓取(Join fetching)

  连接抓取是指Hibernate在获得关联对象时会在SELECT语句中使用外连接的方式来获得关联对象。

   查询抓取(Select fetching)

  查询抓取是指Hibernate通过另外一条SELECT语句来抓取当前对象的关联对象的方式。这也是通过外键的方式来执行数据库的查询。与连接抓取的区别在于,通常情况下这个SELECT语句不是立即执行的,而是在访问到关联对象的时候才会执行。

   子查询抓取(Subselect fetching)

  子查询抓取也是指Hibernate通过另外一条SELECT语句来抓取当前对象的关联对象的方式。与查询抓取的区别在于它所采用的SELECT语句的方式为子查询,而不是通过外连接。

   批量抓取(Batch fetching)

  批量抓取是对查询抓取的优化,它会依据主键或者外键的列表来通过单条SELECT语句实现管理对象的批量抓取。

  以上介绍的是Hibernate 3所提供的抓取策略,也就是抓取关联对象的手段。为了提升系统的性能,在抓取关联对象的时机上,还有以下一些选择。
立即抓取(Immediate fetching)

  立即抓取是指宿主对象被加载时,它所关联的对象也会被立即加载。

   延迟集合抓取(Lazy collection fetching)

  延迟集合抓取是指在加载宿主对象时,并不立即加载它所关联的对象,而是到应用程序访问关联对象的时候才抓取关联对象。这是集合关联对象的默认行为。

   延迟代理抓取(Lazy proxy fetching)

  延迟代理抓取是指在返回单值关联对象的情况下,并不在对其进行get操作时抓取,而是直到调用其某个方法的时候才会抓取这个对象。

   延迟属性加载(Lazy attribute fetching)

  延迟属性加载是指在关联对象被访问的时候才进行关联对象的抓取。

  介绍了Hibernate所提供的关联对象的抓取方法和抓取时机,这两个方面的因素都会影响Hibernate的抓取行为,最重要的是要清楚这两方面的影响是不同的,不要将这两个因素混淆,在开发中要结合实际情况选用正确的抓取策略和合适的抓取时机。

  抓取时机的选择

  在Hibernate 3中,对于集合类型的关联在默认情况下会使用延迟集合加载的抓取时机,而对于返回单值类型的关联在默认情况下会使用延迟代理抓取的抓取时机。

  对于立即抓取在开发中很少被用到,因为这很可能会造成不必要的数据库操作,从而影响系统的性能。当宿主对象和关联对象总是被同时访问的时候才有可能会用到这种抓取时机。另外,使用立即连接抓取可以通过外连接来减少查询SQL语句的数量,所以,也会在某些特殊的情况下使用。

  然而,延迟加载又会面临另外一个问题,如果在Session关闭前关联对象没有被实例化,那么在访问关联对象的时候就会抛出异常。处理的方法就是在事务提交之前就完成对关联对象的访问。

  所以,在通常情况下都会使用延迟的方式来抓取关联的对象。因为每个立即抓取都会导致关联对象的立即实例化,太多的立即抓取关联会导致大量的对象被实例化,从而占用过多的内存资源。

  抓取策略的选取

  对于抓取策略的选取将影响到抓取关联对象的方式,也就是抓取关联对象时所执行的SQL语句。这就要根据实际的业务需求、数据的数量以及数据库的结构来进行选择了。

  在这里需要注意的是,通常情况下都会在执行查询的时候针对每个查询来指定对其合适的抓取策略。指定抓取策略的方法如下所示:

  User user = (User) session.createCriteria(User.class)

  .setFetchMode("permissions", FetchMode.JOIN)

  .add( Restrictions.idEq(userId) )

  .uniqueResult();

  五、 查询性能提升小结

  在本小节中介绍了查询性能提升的方法,关键是如何通过优化SQL语句来提升系统的查询性能。查询方法和抓取策略的影响也是通过执行查询方式和SQL语句的多少来改变系统的性能的。这些都属于开发人员所应该掌握的基本技能,避免由于开发不当而导致系统性能的低下。

  在性能调整中,除了前面介绍的执行SQL语句的因素外,对于缓存的使用也会影响系统的性能。通常来说,缓存的使用会增加系统查询的性能,而降低系统增加、修改和删除操作的性能(因为要进行缓存的同步处理)。所以,开发人员应该能够正确地使用有效的缓存来提高数据查询的性能,而要避免滥用缓存而导致的系统性能变低。在采用缓存的时候也应该注意调整自己的检索策略和查询方法,这三者配合起来才可以达到最优的性能。

  另外,事务的使用策略也会影响到系统的性能。选取正确的事务隔离级别以及使用。
分享到:
评论

相关推荐

    hibernate性能优化方案

    ### Hibernate性能优化方案详解 #### 一、引言 Hibernate作为Java领域中广泛使用的对象关系映射(ORM)框架,其高效性和灵活性受到众多开发者的青睐。然而,不当的设计和配置往往会导致性能瓶颈,严重影响应用程序...

    Hibernate的详解

    **Hibernate详解** Hibernate是一款强大的Java持久化框架,它简化了数据库与Java对象之间的交互,使得开发者无需关注SQL的编写,可以更加专注于业务逻辑。本文将深入探讨Hibernate的核心概念、主要功能以及如何在...

    hibernate包详解+hibernatePPT

    提供的`hibernatePPT`可能是对Hibernate框架的深入讲解,包括基本概念、配置、操作、查询、性能优化等方面,适合初学者和进阶者学习。通过PPT,你可以更加直观地理解Hibernate的工作原理和最佳实践。 总结来说,...

    hibernate 优化方案

    ### Hibernate优化方案详解 在企业级应用开发中,Hibernate作为一款优秀的对象关系映射(ORM)框架,极大地简化了数据库操作。然而,在处理大量数据或复杂查询时,Hibernate的性能问题逐渐凸显。本文将深入探讨...

    Hibernate包作用详解

    - **c3p0.jar**和**proxool.jar**:它们是数据库连接池实现,Hibernate可以配置使用这些连接池来提高性能和资源管理,但如果你已经有了其他的连接池解决方案,它们不是必需的。 总的来说,理解Hibernate的各个jar包...

    精通Hibernate:Java持久化对象技术详解[第二版]

    8. **实体生命周期**:详解Hibernate对对象状态的管理,包括瞬时态、持久态、游离态和脱管态,以及对象状态转换和事件监听器。 9. **多态和继承映射**:讲解如何处理类的继承关系,实现多态查询,包括单表继承、...

    hibernate持久化技术详解.孙卫琴.代码2

    **hibernate持久化技术详解** Hibernate是一款强大的Java对象关系映射(ORM)框架,它为开发者提供了在Java应用中操作数据库的强大工具。通过Hibernate,开发者可以将数据库操作转化为对Java对象的操作,大大降低了...

    Hibernate 培训详解(doc和源代码)

    **Hibernate 框架详解** Hibernate 是一个开源的对象关系映射(ORM)框架,它为 Java 开发者提供了数据持久化的解决方案,简化了数据库操作。本篇将详细讲解 Hibernate 的核心概念、配置、实体类、映射文件以及常用...

    Hibernate第3版开发手册详解.pdf

    Hibernate是Java世界中最流行的持久化解决方案之一,它提供了对JDBC的封装,允许开发者以面向对象的方式来操作数据库,而无需关心底层的SQL语句。Hibernate第3版相比前一版本,在性能、功能和易用性上都有显著提升,...

    hibernate趣味详解

    Hibernate支持一对一、一对多、多对一、多对多等多种关联映射,理解这些关联关系的实现方式及优化策略是深入使用Hibernate的重点。 10. **性能优化** 通过合理配置缓存、批处理、懒加载等策略,可以显著提升...

    Hibernate各种主键生成策略与配置详解

    在使用Hibernate进行持久化操作时,合理选择和配置主键生成策略对于确保数据的一致性和优化性能至关重要。本文将详细介绍几种常见的主键生成策略,并结合示例代码帮助读者更好地理解和运用。 #### 二、assigned - ...

    Java开源项目Hibernate包作用详解

    ### Java开源项目Hibernate包作用详解 #### 概述 Hibernate是一个强大的对象关系映射(Object-Relational Mapping,简称ORM)框架,它极大地简化了Java应用程序与数据库交互的过程。通过Hibernate,开发者能够更加...

    Hibernate二级缓存配置详解

    《Hibernate二级缓存配置详解》 在Java的持久化框架Hibernate中,缓存技术是提升系统性能的关键之一。本文将深入探讨Hibernate的二级缓存,包括其事务范围、进程范围和集群范围的配置,特别是关注进程范围内的...

    hibernate关联映射详解SSH 多对多,一对多关系对象映射

    本篇文章将深入探讨Hibernate中的一对多和多对多关系映射。 首先,让我们理解一对多关联映射。在数据库中,一对多关系意味着一个表中的记录可以与另一个表中的多个记录相关联。在Hibernate中,这可以通过在实体类中...

    hibernate+ehcache

    【标题】:“Hibernate + Ehcache 整合使用详解” 【描述】:“Hibernate 是一款流行的 Java 持久层框架,而 Ehcache 是一个高效的分布式内存缓存系统。将两者结合,能够极大地提升应用的性能,减少数据库的负载,...

    hibernate4.0

    《Hibernate 4.0 开发核心包详解》 Hibernate,作为一个强大的对象关系映射(ORM)框架,一直是Java开发者在数据库交互方面的首选工具。而Hibernate 4.0版本的发布,为开发者带来了更为完善的功能和优化的性能。...

    Struts 2+Hibernate+Spring整合开发技术详解 6~11章

    这本书《Struts 2+Hibernate+Spring整合开发技术详解》由蒲子明撰写,由清华大学出版社出版,提供了6至11章的源码分析,帮助读者深入理解这三大框架的集成与应用。 6章到11章的内容可能涵盖了以下几个关键知识点: ...

Global site tag (gtag.js) - Google Analytics