Hibernate优化共15页文档_第1页
Hibernate优化共15页文档_第2页
Hibernate优化共15页文档_第3页
Hibernate优化共15页文档_第4页
Hibernate优化共15页文档_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1. 抓取优化抓取是指 Hibernate 如何在关联关系之间进行导航的时候, Hibernate 如何获取关联对象的策略,其主要定义了两个方面:如何抓取和何时抓取。1)如何抓取。Hibernate3 主要有两种抓取方式,分别应用于对象关联实例(many-to-one、one-to-one)和对象关联集合(set、map等),总共是四种变种:JOIN抓取: 通过在SELECT语句中使用OUTER JOIN获得对象的关联实例或者关联集合)SELECT取:另外发送一条SELECT语句来抓取当前对象的关联实体和集合在我的开发经历中,此处对性能的优化是比较有限的,并不值得过多关注例:A. 应用于对象关

2、联实例(默认是false )<many-to-one name="." outer-join="true/false/auto"./>B. 应用于对象关联集合(默认是auto )<set name="." fetch="join/select" . ></set>2)何时抓取主要分为 延迟加载和立即抓取 ,默认的情况下 Hibernate3 对对象关联 实采用延迟加载, 普通属性采用立即抓取 ,通过延迟加载和采用适当的抓取粒度,与不采用优化相 比往往可以将性能提升数倍。立即抓取:

3、 当抓取宿主对象时,同时抓取其关联对象和关联集以及属性延迟加载:当抓取宿主对象时,并不抓取其关联对象,而是当对其对象进行调用时才加载。例:A. 应用于对象关联实例(默认是延迟加载)<many-to-one name="."lazy="true/false" ./>B. 应用于对象关联集合(默认是延迟加载)<set name="." lazy="true/false" . ></set>对于延迟加载,需要注意的时,对延迟对象的使用必须在 Session 关闭之前进行, Hibern

4、ate 的 LazyInitalizationException 往往就是由于在 Session 的生命期外使用 了延迟加载的对象。当我们进行Web开发时,可以使用OpenSessionInView模式,当请求开始时打开session,当请求响应结束时才关闭session,不过,在使用OpenSessionInView 模式时,需要注意如果响应时间比较长(业务比较复杂或者客户端是低速网络),将Session 资源(也就是数据库的连接 )占用太久的话可以会导致资源耗尽。3)抓取粒度抓取粒度指的是对象在关联关系之间被导航时一次预先加载的数量,Hibernate 程序的性能比较差往往就在于没有对抓取

5、粒度仔细考虑, 当加载一个列表并在列表中的每个对象中对其关联进行导航时,往往导致N+1条SQL语句查询。例:A. 应用于对象关联实例(默认为 1),注意,对对象关联实例的设置是在被关联的对象之上的,譬如class UserGroup g;那么抓取粒度应该在 Group 的配置文件之上,见下<class name="Group" table="group"batch-size="."></class>对该值并没有一个约定俗成的值,根据情况而定,如果被关联表数据比较少,则可以设置地小一些,3-20 ,如果比较大则可

6、以设到 30-50 ,注意的时候,并不是越多越好,当其值超过 50 之后,对性能并没有多大改善但却无谓地消耗内存假设有如下例子:List<User> users = query.list();如果有20个User,并对这20个User及其Group进行遍历,如果不设置 batch-size (即batch-size="1"),则在最糟糕的情况下,需要1 + 20条SQL语句,如果设置batch-size="10",则最好的情况下只需要1 + 2条SQL语句。B. 应用于对象关联集合(默认为 1)<set name=".&quo

7、t; batch-size="" . ></set>2. 二级缓存Hibernate 对数据的缓存包括两个级: 一级缓存, 在 Session 的级别上进行, 主要是对象缓存, 以其 id 为键保存对象, 在 Session 的生命期间存在; 二级缓存, 在 SessionFactory 的级别上进行,有对象缓存和查询缓存,查询缓存以查询条件为键保存查询结果,在 SessionFactory 的生命期间存在。默认地, Hibernate 只 启用一级缓存,通过正确地使用二级缓存,往往可以获得意想不到的性能。1)对象缓存:当抓取一个对象之后, Hiberat

8、e 将其以 id 为键缓存起来,当下次碰到抓取 id 相同的对象时,可以使用如下配置。方法 1:在缓存对象上配置<class .><cache useage="read-only/write/" regions="group" /></class>useage 表示使用什么类型的缓存,譬如只读缓存、读写缓存等等(具体参见 Hibernate 参考指南),值得注意的时,有部分缓存在 Hibernate 的实现中不支持读写缓存,譬如 JBossCache 在 Hibernate 的实现中只是一种只读缓存,具体缓存实现对缓存

9、类型的支持情况,可以参见 org.hibernate.cache 包regions 表示缓存分块,大部分的缓存实现往往对缓存进行分块,该部分是可选的,详细参见各缓存实现。方法 2:在 hibernate.cfg.xml 中配置<cache class="." useage="." regions="."/>我认为第二种更好,可以统一管理。2) 查询缓存查询时候将查询结果以查询条件为键保存起来,需要配置如下A. 在 hibernate.cfg.xml 中配置(启用查询缓存)vproperty name="hiber

10、nate.cache.use_query_cache">true</property>(前面的属性名可参见常量org.hibernate.cfg.Enviroment.USE_QUERY_CACHE )。B.程序query.setCacheable(true);query.setCacheRegions(.);需要注意的是 ,查询缓存与对象缓存 要结合更有效 , 因为查询缓存仅缓存查询结果列表的主键数据一般情况下在开发中, 对一些比较稳定而又被频繁引用的数据, 譬如数据 字典之类的,将其进行二级缓存,对一些查询条件和查询数据变化不频繁而又常常被使用的查询,将其进行二

11、级缓存 。由于二级缓存是放在内存中,而且 Hibernate 的缓存不是弱引用缓存(WeekReference),所以注意不要将大块的数据放入其中,否则可能会被内存造成比较大的压力。3. 批量数据操作当进行大批量数据操作(几万甚至几十几百万)时,需要注意两点,一,批量提交,二,及时清除不需要的一级缓存数据1) 所谓的批量提交,就是不要频繁使用session的flush,每一次进行flush,Hibernate将P0数据于数据库进行同步,对于海量级数据操作来说是性能灾难(同时提交几千条数据和提交一条数据 flush 一次性能差别可能会是几十倍的差异)。一般将数据操作放在事务中,当事务提交时Hib

12、ernate 自动帮你进行 flush 操作。2) 及时清除不需要的一级缓存数据:由于Hibernate 默认采用一级缓存,而在 session 的生命期间,所有数据抓取之后会放入一级缓存中,而当数据规模比较庞大时,抓取 到内存中的数据会让内存压力非常大,一般分批操作数据,被一次操作之后将一级缓存清除,譬如session.clear(User.class)4. 杂项dynamic-insert , dynamic-update ,动态插入和动态更新, 指的是让 Hibernate 插入数据时仅插入非空数据,当修改数据时只修改变化的数据,譬如对于class User id usernamepas

13、sword如果 u.id=1, u.username="ayufox",u.password=null ,那么如果不设置动态插入,则其 sql 语句是 insert into users(id, username, password) values (1, 'ayufox', ') ,如果设置则其 sql 语句是 insert into users(username) valeus('ayufox')在如上的情况下,如果修改 u.password='11' ,那么如果不设置动态更新,则 sql 语句为 update u

14、sers set username='ayufox', password='11' where id = 1,如果设置则为 update user set password='11' where d = 1设置是在 class 的映射文件中,如下<class name="User" table="users" dynamic=insert="true/false" dynamic-update="true/false" .></class>该设

15、置对性能的提升比较有限Hibernate 优化方案一、 批量修改和删除在 Hibernate 2 中,如果需要对任何数据进行修改和删除操作,都需要先执行查询操作,在得到要修改或者删除的数据后,再对该数据进行相应的操作处理。在数据量少的情况下采用这种处理方式没有问题,但需要处理大量数据的时候就可能存在以下的问题:占用大量的内存。需要多次执行 update/delete 语句,而每次执行只能处理一条数据。以上两个问题的出现会严重影响系统的性能。因此,在Hiber nate 3中引入了用于批量更新或者删除数据的HQL语句。这样,开发人员就可以一次更新或者删除多条记录,而不用每次都一个一个地修改或者删

16、除记录了。如果要删除所有的 User对象(也就是User对象所对应表中的记录),则可以直接使用下面的 HQL语句:delete User而在执行这个HQL语句时,需要调用 Query对象的executeUpdate()方法,具体的实例如下所示:String HQL="delete User"Query query=session.createQuery(HQL);int size=query.executeUpdate();采用这种方式进行数据的修改和删除时与直接使用JDBC的方式在性能上相差无几,是推荐使用的正确方法。如果不能采用HQL 语句进行大量数据的修改,也就是说只

17、能使用取出再修改的方式时,也会遇到批量插入时的内存溢出问题,所以也要采用上面所提供的处理方法来进行类似的处理。二、使用SQL执行批量操作在进行批量插入、修改和删除操作时,直接使用JDBC来执行原生态的SQL语句无疑会获得最佳的性能,这是因为在处理的过程中省略或者简化了以下处理内容: HQL语句到SQL语句的转换。 Java 对象的初始化。 Java 对象的缓存处理。但是在直接使用JDBC执行SQL语句时,有一个最重要的问题就是要处理缓存中的Java对象。因为通过这种底层方式对数据的修改将不能通知缓存去进行相应的更新操作,以保证缓存中的对象与数据库中的数据是一致的。提升数据库查询的性能数据库查询

18、性能的提升也是涉及到开发中的各个阶段,在开发中选用正确的查询方法无疑是最基础也最简单的。1、SQL语句的优化使用正确的SQL语句可以在很大程度上提高系统的查询性能。获得同样数据而采用不同方式的SQL语句在性能上的差距可能是十分巨大的。由于Hibernate是对JDBC的封装,SQL语句的产生都是动态由 Hibernate自动完成的。Hibernate 产生SQL语句的方式有两种:一种是通过开发人员编写的HQL语句来生成,另一种是依据开发人员对关联对象的访问来自动生成相应的SQL语句。至于使用什么样的SQL语句可以获得更好的性能要依据数据库的结构以及所要获取数据的具体情况来进行处理。在确定了所要

19、执行的SQL语句后,可以通过以下三个方面来影响Hibernate所生成的SQL语句:HQL语句的书写方法。查询时所使用的查询方法。对象关联时所使用的抓取策略。2 、使用正确的查询方法一种是得到单个持久化对象的 get() 方法和 load() 方法,另一种是 Query 对象的 list() 方法和 iterator() 方在前面已经介绍过,执行数据查询功能的基本方法有两种:法。 在开发中应该依据不同的情况选用正确的方法。get() 方法和 load() 方法的区别在于对二级缓存的使用上。load() 方法会使用二级缓存,而 get() 方法在一级缓存没有找到的情况下会直接查询数据库,不会去二

20、级缓存中查找。在使用中,对使用了二级缓存的对象进行查询时最好使用load() 方法,以充分利用二级缓存来提高检索的效率。list() 方法和 iterator() 方法之间的区别可以从以下几个方面来进行比较。执行的查询不同list() 方法在执行时,是直接运行查询结果所需要的查询语句,而 iterator() 方法则是先执行得到对象 ID 的查询,然后再根据每个 ID 值去取得所要查询的对象。因此, 对于list()方式的查询通常只会执行一个SQL语句,而对于iterator。方法的查询则可能需要执行N+1条SQL语句(N为结果集中的记录数)。iterator。方法只是可能执行 N+1条数据,

21、具体执行SQL语句的数量取决于缓存的情况以及对结果集的访问情况。缓存的使用list() 方法 只能使用二级缓存中的查询缓存,而无法使用二级缓存对单个对象的缓存 (但是会把查询出的对象放入二级缓存中 ) 。所以,除非重复执行相同的查询操作, 否则无法利用缓存的机制来提高查询的效率。iterator() 方法则可以充分利用二级缓存,在根据 ID 检索对象的时候会首先到缓存中查找,只有在找不到的情况下才会执行相应的查询语句。所以,缓存中对象的存在 与否会影响到SQL语句的执行数量。对于结果集的处理方法不同list() 方法会一次获得所有的结果集对象, 而且它会依据查询的结果初始化所有的结果集对象。

22、这在结果集非常大的时候必然会占据非常多的内存, 甚至会造成内存溢出 情况的发生。iterator() 方法在执行时不会一次初始化所有的对象,而是根据对结果集的访问情况来初始化对象。因此在访问中可以控制缓存中对象的数量,以避 免占用过多缓存, 导致内存溢出情况的发生。使用 iterator() 方法的另外一个好处是,如果只需要结果集中的部分记录,那么没有被用到的结果对象根本 不会被初始化。所以,对结果集的访 问情况也是调用iterator。方法时执行数据库SQL语句多少的一个因素。所以,在使用 Query 对象执行数据查询时应该从以上几个方面去考虑使用何种方法来执行数据库的查询操作。四、 使用正

23、确的抓取策略所谓抓取策略(fetching strategy)是指当应用程序需要利用关联关系进行对象获取的时候,Hibernate获取关联对象的策略。抓取策略可以在0/R映射的元数据中声明,也可以在特定的HQL或条件查询中声明。Hibernate 3 定义了以下几种抓取策略。连接抓取 (Join fetching)连接抓取是指Hibernate在获得关联对象时会在 SELECT语句中使用外连接的方式来获得关联对象。查询抓取 (Select fetching)查询抓取是指Hibernate通过另外一条SELECTS句来抓取当前对象的关联对象的方式。这也是通过外键的方式来执行数据库的查询。与连接抓

24、取的区别在于,通常情况下这个SELECT吾句不是立即执行的,而是在访问到关联对象的时候才会执行。子查询抓取 (Subselect fetching)子查询抓取也是指 Hibernate通过另外一条SELECT吾句来抓取当前对象的关联对象的方式。与查询抓取的区别在于它所采用的SELECT吾句的方式为子查询, 而不是通过外连接。批量抓取 (Batch fetching)批量抓取是对查询抓取的优化,它会依据主键或者外键的列表来通过单条SELECT吾句实现管理对象的批量抓取。以上介绍的是 Hibernate 3 所提供的抓取策略,也就是抓取关联对象的手段。为了提升系统的性能,在抓取关联对象的时机上,还

25、有以下一些选择。立即抓取 (Immediate fetching)立即抓取是指宿主对象被加载时,它所关联的对象也会被立即加载。延迟集合抓取 (Lazy collection fetching)延迟集合抓取是指在加载宿主对象时,并不立即加载它所关联的对象,而是到应用程序访问关联对象的时候才抓取关联对象。这是集合关联对象的默认行为。延迟代理抓取 (Lazy proxy fetching)延迟代理抓取是指在返回单值关联对象的情况下,并不在对其进行 get 操作时抓取,而是直到调用其某个方法的时候才会抓取这个对象。延迟属性加载 (Lazy attribute fetching)延迟属性加载是指在关联对

26、象被访问的时候才进行关联对象的抓取。介绍了 Hibernate 所提供的关联对象的抓取方法和抓取时机, 这两个方面的因素都会影响 Hibernate 的抓取行为, 最重要的是要清楚这两方面的影响是不同的, 不要将这 两个因素混淆,在开发中要结合实际情况选用正确的抓取策略和合适的抓取时机。抓取时机的选择在 Hibernate 3 中,对于集合类型的关联在默认情况下会使用延迟集合加载的抓取时机,而对于返回单值类型的关联在默认情况下会使用延迟代理抓取的抓取时机。对于立即抓取在开发中很少被用到,因为这很可能会造成不必要的数据库操作,从而影响系统的性能。当宿主对象和关联对象总是被同时访问的时候才有可能会

27、 用到这 种抓取时机。另外,使用立即连接抓取可以通过外连接来减少查询SQL语句的数量,所以,也会在某些特殊的情况下使用。然而, 延迟加载又会面临另外一个问题, 如果在 Session 关闭前关联对象没有被实例化, 那么在访问关联对象的时候就会抛出异常。 处理的方法就是在事务提交之前就完 成对关联对象的访问。所以, 在通常情况下都会使用延迟的方式来抓取关联的对象。 因为每个立即抓取都会导致关联对象的立即实例化, 太多的立即抓取关联会导致大量的对象被实例化, 从而 占用过多的内存资源。抓取策略的选取对于抓取策略的选取将影响到抓取关联对象的方式,也就是抓取关联对象时所执行的SQL语句。这就要根据实际

28、的业务需求、数据的数量以及数据库的结构来进行选择了。在这里需要注意的是,通常情况下都会在执行查询的时候针对每个查询来指定对其合适的抓取策略。指定抓取策略的方法如下所示:User user = (User) session.createCriteria(User.class).setFetchMode("permissions", FetchMode.JOIN).add( Restrictions.idEq(userId) ).uniqueResult();五、 查询性能提升小结在本小节中介绍了查询性能提升的方法,关键是如何通过优化 SQL语句来提升系统的查询性能。 查询方法

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

30、事务隔离级别以及使用。Hibernate 中二级缓存的配置和使用(一) Hibernate的二级缓存策略的一般过程如下:1)条件查询的时候,总是发出一条 select * from table_name where.(选择所有字段)这样的SQL语句查询数据库, 一次获得所有的数据对象。2)把获得的所有数据对象根据 ID 放入到第二级缓存中。3)当 Hibernate 根据 ID 访问数据对象的时候,首先从 Session 一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID 放入到缓存。4)删除、更新、增加数据的时候,同时更新缓存。Hibernat

31、e 的二级缓存策略,是针对于 ID 查询的缓存策略,对于条件查询则毫无作用。 为此, Hibernate 提供了针对条件查询的 Query Cache 。(二)什么样的数据适合存放到第二级缓存中?1 很少被修改的数据2 不是很重要的数据,允许出现偶尔并发的数据3 不会被并发访问的数据4 参考数据 , 指的是供应用参考的常量数据,它的实例数目有限,它的实例会被许多其他类的实例引用,实例极少或者从来不会被修改。(三)不适合存放到第二级缓存的数据?1 经常被修改的数据2 财务数据,绝对不允许出现并发3 与其他应用共享的数据。实践部分:使用EhCache配置二级缓存:配置准备:1)把 ehcache-

32、1.2.3.jar 加入到当前应用的 classpath 中。2)在hibernate.cfg.xml文件中加入 EhCache缓存插件的提供类。1. <!- 配置缓存插件->2. <propertyname="vider_class">3. org.hibernate.cache.EhCacheProvider4. </property>3)挎贝 ehcache.xml 文件到类路径 ( 项目工程的 src 目录下 ),这个文件在 Hibernate 安装目录的 etc 下。配置步骤:Hiberna

33、te 允许在类和集合的粒度上设置第二级缓存。在映射文件中,class和set元素都有一个cache子元素,这个子元素用来配置二级缓存。示例:以 category( 产品类别 ) 和 product( 产品 ) 的映射为例:1) 修改要配置缓存的那个持久化类的对象关系映射文件:1.Category.hbm.xml<?xml version="1.0" encoding="utf-8"?>Hibernate 允许在类和集合的粒度上设置第二级缓存。在映射文件中,class和set元素都有一个cache子元素,这个子元素用来配置二级缓存。Hibern

34、ate 允许在类和集合的粒度上设置第二级缓存。在映射文件中,class和set元素都有一个cache子元素,这个子元素用来配置二级缓存。2.<!DOCTYPE hibernate-mapping PUBLIC "-/Hibernate/HibernateMapping DTD 3.0/EN"Hibernate 允许在类和集合的粒度上设置第二级缓存。在映射文件中,class和set元素都有一个cache子元素,这个子元素用来配置二级缓存。3."http:/hibernate.sourceforge/hibernate-mapping-3.0.dtd"

35、>Hibernate 允许在类和集合的粒度上设置第二级缓存。在映射文件中,class和set元素都有一个cache子元素,这个子元素用来配置二级缓存。Hibernate 允许在类和集合的粒度上设置第二级缓存。在映射文件中,class和set元素都有一个cache子元素,这个子元素用来配置二级缓存。4.<hibernate-mapping>5.<class name="org.qiujy.domain.cachedemo.Category"table="categories">6.配置缓存 , 必须紧跟在 class 元素后面

36、7.对缓存中的 Category 对象采用读写型的并发访问策略8.<cache usage="read-write"/>9.<id name="id" type="java.lang.Long">10.<column name="id" />11.<generator class="native" />12.</id>13.!-配置版本号 , 必须紧跟在 id 元素后面14.<version name="version&

37、quot; column="version" type="java.lang.Long"/>15.<property name="name" type="java.lang.String">16.<column name="name" length="32" not-null="true"/>17.</property>18.<property name="description" typ

38、e="java.lang.String">19.<column name="description" length="255"/>20.</property>21.<set name="products" table="products"cascade="all" inverse="true">22.!-Hibernate 只会缓存对象的简单属性的值23.要缓存集合属性,必须在集合元素中也加入cache子元素24.

39、而Hibernate仅仅是把与当前持久对象关联的对象的OID存放到缓存中。25.如果希望把整个关联的对象的所有数据都存入缓存26.则要在相应关联的对象的映射文件中配置cache 元素27.<cache usage="read-write"/>28.<key column="categoryId" not-null="true"/>29.<one-to-many class="org.qiujy.domain.cachedemo.Product"/>30.</set>3

40、1.</class>32.</hibernate-mapping>Hibernate 允许在类和集合的粒度上设置第二级缓存。在映射文件中,class和set元素都有一个cache子元素,这个子元素用来配置二级缓存。Hibernate 允许在类和集合的粒度上设置第二级缓存。在映射文件中,class和set元素都有一个cache子元素,这个子元素用来配置二级缓存。Product.hbm.xmlHibernate 允许在类和集合的粒度上设置第二级缓存。在映射文件中,class和set元素都有一个cache子元素,这个子元素用来配置二级缓存。Hibernate 允许在类和集合的

41、粒度上设置第二级缓存。在映射文件中,class和set元素都有一个cache子元素,这个子元素用来配置二级缓存。1.<?xml version="1.0"encoding="utf-8"?>2.<!DOCTYPE hibernate-mapping PUBLIC "-/Hibernate/HibernateMapping DTD 3.0/EN"Hibernate 允许在类和集合的粒度上设置第二级缓存。在映射文件中,class和set元素都有一个cache子元素,这个子元素用来配置二级缓存。3."http:/

42、hibernate.sourceforge/hibernate-mapping-3.0.dtd">4.<hibernate-mapping>5.<class name="org.qiujy.domain.cachedemo.Product"table="products">6.<cache usage="read-write"/>7.<idname="id" type="java.lang.Long">8.<column na

43、me="id" />9.<generator class="native" />10.</id>11.<!-配置版本号 , 必须紧跟在 id 元素后面 ->12.<version name="version" column="version" type="java.lang.Long"/>13.<property name="name" type="java.lang.String">14.

44、<column name="name" length="32" not-null="true"/>15.</property>16.<property name="description" type="java.lang.String">17.<column name="description" length="255"/>18.</property>19.<property name=&q

45、uot;unitCost" type="java.lang.Double">20.<column name="unitCost" />21.</property>22.<property name="pubTime" type="java.util.Date">23.<column name="pubTime" not-null="true"/>24.</property>25.<many-to

46、-one name="category"26.column="categoryId"27.class="org.qiujy.domain.cachedemo.Category"28.cascade="save-update"29.not-null="true">30.</many-to-one>31.</class>32.</hibernate-mapping>2) 编辑 ehcache.xml 文件:1.<ehcache>2.<dis

47、kStore path="c:ehcache"/>3.<defaultCache4.maxElementsInMemory="10000"5.eternal="false"6.timeToIdleSeconds="120"7.timeToLiveSeconds="120"8.overflowToDisk="true"9.<!- 设置 Category 类的缓存的数据过期策略->10.<cache name="org.qiujy.doma

48、in.cachedemo.Category"11.maxElementsInMemory="100"12.eternal="true"13.timeToIdleSeconds="0"14.timeToLiveSeconds="0"15.overflowToDisk="false"16.<!-设置 Category 类的 products 集合的缓存的数据过期策略17.<cachename="org.qiujy.domain.cachedemo.Category.p

49、roducts"18.maxElementsInMemory="500"19.eternal="false"20.timeToIdleSeconds="300"21.timeToLiveSeconds="600"22.overflowToDisk="true"23.<cachename="org.qiujy.domain.cachedemo.Product"24.maxElementsInMemory="500"25.eternal=&qu

50、ot;false"26.timeToIdleSeconds="300"27.timeToLiveSeconds="600"28.overflowToDisk="true"29.</ehcache>在 Spring 托管的 Hibernate 中使用二级缓存1 在 spring 的配置文件中, hibernate 部分加入 xml 代码 org.hibernate.cache.EhCacheProvider true2. 为HBM表设置cache策略xml代码3 .在DAO中,调用find 方法查询之前,设置使用缓

51、存 Java代码getHibernateTemplate().setCacheQueries(true);补充: 如果不设置“查询缓存”,那么 hibernate只会缓存使用 load() 方法获得的单个持久化对象,如果想缓存使用 findall() 、list() 、 Iterator() 、createCriteria()、createQuery() 等方法获得的数据结果集的话,就需要设置 hibernate.cache.use_query_cache true 才行。hibernate1. 在数据库中条件查询速度很慢的时候,如何优化 ?(1). 建索引(2) . 减少表之间的关联(3)

52、. 优化 sql ,尽量让 sql 很快定位数据,不要让 sql 做全表查询,应该走索引 , 把数据量大的表排在前面(4) . 简化查询字段,没用的字段不要,已经对返回结果的控制,尽量返回少量数据2. 在 hibernate 中进行多表查询 ,每个表中各取几个字段 ,也就是说查询出来的结果集并没有一个实体类与之对应 ,如何解决这个问题 ?解决方案一,按照 Object 数据取出数据,然后自己组 bean解决方案二,对每个表的 bean 写构造函数,比如表一要查出 field1,field2 两个字段,那么有一个构造函数就是 Bean(type1 filed1,type2 field2) ,然后

53、在 hql 里面就可 以直接生成这个 bean 了。具体怎么用请看相关文档,我说的不是很清楚。hibernate 的核心类是什么,它们的相互关系是什么?重要的方法是什么 ?Configuration 接口:配置 Hibernate ,根据其启动 hibernate ,创建 SessionFactory 对象;SessionFactory 接口:初始化 Hibernate ,充当数据存储源的代理,创建session 对象, sessionFactory 是线程安全的,意味着它的同一个实例可以被应 用的多个线程共享,是重量级、二级缓存;第 10 页Session 接口:负责保存、更新、删除、加载和

54、查询对象,是线程不安全的, 避免多个线程共享同一个 session ,是轻量级、一级缓存;Transaction 接口:管理事务;Query 和 Criteria 接口:执行数据库的查询。Session 如下方法Save/ load/Update/Delete/get/saveOrUpdate/deleteAllQuery q=CreateQuery( “from Customer where customerName=:customerName ”)beginTransactioncloseTransactionCommit()优化 hibernate 性能的几点建议1、针对oracle数据

55、库而言,Fetch Size 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数,一般设置为30、50、100。Oracle数据库的JDBC驱动默认 的 Fetch Size=15 ,设置 Fetch Size 设置为: 30、 50,性能会有明显提升,如果继续增大,超出 100,性能提升不明显,反而会消耗内存。即在 hibernate 配制文件中进行配制:Xml代码1 v propertyname= hibernateProperties>2 v props >3 v propkey=”hibernate.dialect”> org.hiberna

56、te.dialect.Oracle9Dialectv /prop >4 v propkey=”hibernate.show_sql ”> false v /prop >when the JVM starts upCreate/update the database tables automatically> update v /prop >->6 v prop key=”hibernate.hbm2ddl.autoTurn batching off for bettererror messages under PostgreSQL8 v propkey=”h

57、ibernate.jdbc.batch_size”>100v/prop>->9 v propkey=”hibernate.jdbc.batch_size”>50v/prop>10 v/props >Xml代码1. 1 vpropertyname=”hibernateProperties ”>第 11 页2.2< props>3.3v propkey=”hibernate.dialect ”>org.hibernate.dialect.Oracle9Dialectv /prop >4.4v propkey=”hibernate.s

58、how_sql ”>falsev /prop >5.5v !-Create/updatethe databasetables automaticallywhenthe JVM startsup6.6v propkey=”hibernate.hbm2ddl.auto”>update v /prop >->7.7v !-Turnbatching off for bettererror messagesunderPostgreSQL8.8v propkey=”hibernate.jdbc.batch_size”> 100v /prop >->9.9v

59、propkey=”hibernate.jdbc.batch_size”> 50 v /prop >10.10v /props >11.< /property >Fetch Size 设的越大,读数据库的次数越少,速度越快; Fetch Size 越小,读数据库的次数越多,速度越慢。2、 如果是超大的系统,建议生成htm 文件。加快页面提升速度。3、不要把所有的责任推在 hibernate 上,对代码进行重构,减少对数据库的操作,尽量避免在数据库查询时使用 in 操作,以及避免递归查询操作,代码质量、系统设计的合 理性决定系统性能的高低。4、 对大数据量查询时,慎用 list() 或者 iterator() 返回查询结果,(1) . 使用 List() 返回结果时, Hibernate 会所有查询结果初始化为持久化对象,结果集较大时,会占用很多的处理时间。(2) . 而使用 iterator() 返回结果时,在每次调用 iterator.next() 返回对象并使用对象时, Hibernate 才调用查询将对应的对象初始 化,对于大数据量时,每调用一次查询都会花费较多的时间。当结果集较大,但是含有较大量相同的数据,或者结果集不是全部都会使用时,使用iterator() 才有优势。5、 在一对多

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论