`
as619864232
  • 浏览: 324280 次
社区版块
存档分类
最新评论

Hibernate 缓存机制

阅读更多

缓存是位于应用程序与物理数据源之间,用于临时存放复制数据的内存区域,目的是为了减少应用程序对物理数据源访问的次数,从而提高应用程序的运行性能. 
  Hibernate在查询数据时,首先到缓存中去查找,如果找到就直接使用,找不到的时候就会从物理数据源中检索,所以,把频繁使用的数据加载到缓存区后,就可以大大减少应用程序对物理数据源的访问,使得程序的运行性能明显的提升.
 
  
Hibernate缓存分类: 

Session缓存,一级缓存. 

SessionFactory的缓存分为内置缓存和外置缓存.内置缓存中存放的是SessionFactory对象的一些集合属性包含的数据(映射元素据及预定义SQL语句等),对于应用程序来说,它是只读的.外置缓存中存放的是数据库数据的副本,其作用和一级缓存类似.二级缓存除了以内存作为存储介质外,还可以选用硬盘等外部存储设备. 

Hibernate的缓存范围 

Hibernate的一级缓存和二级缓存都位于均位于持久层,且均用于存放数据库数据的副本,最大的区别就是缓存的范围各不一样. 

缓存的范围分为3类: 

1.事务范围 
   事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象形式.缓存的生命周期依赖于事务的生命周期,只有当事务结束时,缓存的生命周期才会结束.事务范围的缓存使用内存作为存储介质,一级缓存就属于事务范围. 
2.应用范围 
   应用程序的缓存可以被应用范围内的所有事务共享访问.缓存的生命周期依赖于应用的生命周期,只有当应用结束时,缓存的生命周期才会结束.应用范围的缓存可以使用内存或硬盘作为存储介质,二级缓存就属于应用范围. 
3.集群范围 
   在集群环境中,缓存被一个机器或多个机器的进程共享,缓存中的数据被复制到集群环境中的每个进程节点,进程间通过远程通信来保证缓存中的数据的一致,缓存中的数据通常采用对象的松散数据形式. 

  Hibernate的缓存管理 

一级缓存的管理: 

  evit(Object obj)  将指定的持久化对象从一级缓存中清除,释放对象所占用的内存资源,指定对象从持久化状态变为脱管状态,从而成为游离对象. 
  clear()  将一级缓存中的所有持久化对象清除,释放其占用的内存资源 
  contains(Object obj) 判断指定的对象是否存在于一级缓存中. 
  flush() 刷新一级缓存区的内容,使之与数据库数据保持同步. 

  二级缓存的管理: 
   
   evict(Class arg0, Serializable arg1)  将某个类的指定ID的持久化对象从二级缓存中清除,释放对象所占用的资源. 
  

Java代码   收藏代码
  1. sessionFactory.evict(Customer.classnew Integer(1));  


   evict(Class arg0)  将指定类的所有持久化对象从二级缓存中清除,释放其占用的内存资源. 
  

Java代码   收藏代码
  1. sessionFactory.evict(Customer.class);  


   evictCollection(String arg0)  将指定类的所有持久化对象的指定集合从二级缓存中清除,释放其占用的内存资源. 
  

Java代码   收藏代码
  1. sessionFactory.evictCollection("Customer.orders");  



Hibernate的二级缓存的配置 

首先,不是所有的数据都适合放在二级缓存中,看一下,什么样的数据适合放在二级缓存中来?什么样的数据不适合放在二级缓存中来? 
  下面这几种情况就不适合加载到二级缓存中: 
  1.经常被修改的数据 
  2.绝对不允许出现并发访问的数据 
  3.与其他应用共享的数据 
  下面这己种情况合适加载到二级缓存中: 
  1.数据更新频率低 
  2.允许偶尔出现并发问题的非重要数据 
  3.不会被并发访问的数据 
  4.常量数据 
  5.不会被第三方修改的数据 

Hibernate的二级缓存功能是靠配置二级缓存插件来实现的,Hibernate为了集成这些插件,Hibernate提供了org.hibernate.cache.CacheProvider借口,它充当缓存插件与Hibernate之间的适配器 . 

常用的二级缓存插件 
EHCache  org.hibernate.cache.EhCacheProvider 
OSCache  org.hibernate.cache.OSCacheProvider 
SwarmCahe  org.hibernate.cache.SwarmCacheProvider 
JBossCache  org.hibernate.cache.TreeCacheProvider 

简单介绍一下EHCache的配置 
hibernate.cfg.xml 

Xml代码   收藏代码
  1. <hibernate-configuration>  
  2.    <session-factory>  
  3.       <!-- 设置二级缓存插件EHCache的Provider类-->  
  4.       <property name="hibernate.cache.provider_class">  
  5.          org.hibernate.cache.EhCacheProvider  
  6.       </property>  
  7.       <!-- 启动"查询缓存" -->  
  8.       <property name="hibernate.cache.use_query_cache">  
  9.          true  
  10.       </property>  
  11.    </session-factory>  
  12.  </hibernate-configuration>  



ehcache.xml 

Xml代码   收藏代码
  1. <ehcache>  
  2.   <!-- maxElementsInMemory为缓存对象的最大数目, eternal设置是否永远不过期,timeToIdleSeconds对象处于空闲状态的最多秒数,timeToLiveSeconds对象处于缓存状态的最多秒数 -->  
  3.   <diskStore path="java.io.tmpdir"/>  
  4.     <defaultCache maxElementsInMemory="10000" eternal="false"  timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true"/>  
  5. </ehcache>  



****.hbm.xml 

Xml代码   收藏代码
  1. <?xml version="1.0" encoding='UTF-8'?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.                             "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.                             "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >  
  5.   
  6. <hibernate-mapping>  
  7.        
  8.    <class>  
  9.        <!-- 设置该持久化类的二级缓存并发访问策略 read-only read-write nonstrict-read-write transactional-->  
  10.        <cache usage="read-write"/>      
  11.    </class>  
  12.   
  13. </hibernate-mapping>  

 

 

上面源自:http://yuanyao.iteye.com/blog/249465

 

 

下面是官方的说法:

21.2. 二级缓存(The Second Level Cache)

Hibernate 的 Session 在事务级别进行持久化数据的缓存操作。 当然,也有可能分别为每个类(或集合),配置集群、或 JVM 级别(SessionFactory 级别)的缓存。你甚至可以为之插入一个集群的缓存。注意,缓存永远不知道其他应用程序对持久化仓库(数据库)可能进行的修改 (即使可以将缓存数据设定为定期失效)。

You have the option to tell Hibernate which caching implementation to use by specifying the name of a class that implements org.hibernate.cache.CacheProvider using the propertyhibernate.cache.provider_class. Hibernate is bundled with a number of built-in integrations with the open-source cache providers that are listed in 表 21.1 “缓存策略提供商(Cache Providers)”. You can also implement your own and plug it in as outlined above. Note that versions prior to Hibernate 3.2 use EhCache as the default cache provider.

表 21.1. 缓存策略提供商(Cache Providers)

Cache Provider class Type Cluster Safe Query Cache Supported
Hashtable (not intended for production use) org.hibernate.cache.HashtableCacheProvider memory   yes
EHCache org.hibernate.cache.EhCacheProvider memory, disk, transactional, clustered yes yes
OSCache org.hibernate.cache.OSCacheProvider memory,disk   yes
SwarmCache org.hibernate.cache.SwarmCacheProvider clustered (ip multicast) yes (clustered invalidation)  
JBoss Cache 1.x org.hibernate.cache.TreeCacheProvider clustered (ip multicast), transactional yes (replication) yes (clock sync req.)
JBoss Cache 2 org.hibernate.cache.jbc.JBossCacheRegionFactory clustered (ip multicast), transactional yes (replication or invalidation) yes (clock sync req.)

21.2.1. 缓存映射(Cache mappings)

As we have done in previous chapters we are looking at the two different possibiltites to configure caching. First configuration via annotations and then via Hibernate mapping files.

By default, entities are not part of the second level cache and we recommend you to stick to this setting. However, you can override this by setting the shared-cache-mode element in yourpersistence.xml file or by using the javax.persistence.sharedCache.mode property in your configuration. The following values are possible:

  • ENABLE_SELECTIVE (Default and recommended value): entities are not cached unless explicitly marked as cacheable.

  • DISABLE_SELECTIVE: entities are cached unless explicitly marked as not cacheable.

  • ALL: all entities are always cached even if marked as non cacheable.

  • NONE: no entity are cached even if marked as cacheable. This option can make sense to disable second-level cache altogether.

The cache concurrency strategy used by default can be set globaly via thehibernate.cache.default_cache_concurrency_strategy configuration property. The values for this property are:

  • read-only

  • read-write

  • nonstrict-read-write

  • transactional

注意

It is recommended to define the cache concurrency strategy per entity rather than using a global one. Use the @org.hibernate.annotations.Cache annotation for that.

例 21.5. Definition of cache concurrency strategy via @Cache

@Entity 
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Forest { ... }

Hibernate also let's you cache the content of a collection or the identifiers if the collection contains other entities. Use the @Cache annotation on the collection property.

例 21.6. Caching collections using annotations

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="CUST_ID")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public SortedSet<Ticket> getTickets() {
    return tickets;
}

例 21.7 “@Cache annotation with attributes”shows the @org.hibernate.annotations.Cache annotations with its attributes. It allows you to define the caching strategy and region of a given second level cache.

例 21.7. @Cache annotation with attributes

@Cache(
    CacheConcu(1)rrencyStrategy usage();
    String reg(2)ion() default "";
    String inc(3)lude() default "all";
)

1

usage: the given cache concurrency strategy (NONE, READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL)

2

region (optional): the cache region (default to the fqcn of the class or the fq role name of the collection)

3

include (optional): all to include all properties, non-lazy to only include non lazy properties (default all).


Let's now take a look at Hibernate mapping files. There the <cache> element of a class or collection mapping is used to configure the second level cache. Looking at 例 21.8 “The Hibernate <cache> mapping element” the parallels to anotations is obvious.

例 21.8. The Hibernate <cache> mapping element

<cache
    usage="tra(1)nsactional|read-write|nonstrict-read-write|read-only"
    region="Re(2)gionName"
    include="a(3)ll|non-lazy"
/>

1

usage(必须)说明了缓存的策略:transactional、 read-writenonstrict-read-write 或 read-only

2

region (可选,默认为类或者集合的名字(class or collection role name)) 指定第二级缓存的区域名(name of the second level cache region)

3

include(可选,默认为 all) non-lazy 当属性级延迟抓取打开时,标记为 lazy="true" 的实体的属性可能无法被缓存


Alternatively to <cache>, you can use <class-cache> and <collection-cache> elements inhibernate.cfg.xml.

Let's now have a closer look at the different usage strategies

21.2.2. 策略:只读缓存(Strategy:read only)

如果你的应用程序只需读取一个持久化类的实例,而无需对其修改, 那么就可以对其进行只读 缓存。这是最简单,也是实用性最好的方法。甚至在集群中,它也能完美地运作。

21.2.3. 策略:读写/缓存(Strategy:read/write)

如果应用程序需要更新数据,那么使用读/写缓存 比较合适。 如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolation level),那么就决不能使用这种缓存策略。 如果在 JTA 环境中使用缓存,你必须指定hibernate.transaction.manager_lookup_class 属性的值, 通过它,Hibernate 才能知道该应用程序中 JTA 的TransactionManager的具体策略。 在其它环境中,你必须保证在 Session.close()、或 Session.disconnect() 调用前, 整个事务已经结束。 如果你想在集群环境中使用此策略,你必须保证底层的缓存实现支持锁定(locking)。Hibernate 内置的缓存策略并不支持锁定功能。

21.2.4. 策略:非严格读/写缓存(Strategy:nonstrict read/write)

如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离,那么比较适合使用非严格读/写缓存策略。如果在 JTA 环境中使用该策略,你必须为其指定hibernate.transaction.manager_lookup_class 属性的值,在其它环境中,你必须保证在Session.close()、或Session.disconnect() 调用前,整个事务已经结束。

21.2.5. 策略:事务缓存(transactional)

Hibernate 的事务缓存策略提供了全事务的缓存支持,例如对 JBoss TreeCache 的支持。这样的缓存只能用于 JTA 环境中,你必须指定为其 hibernate.transaction.manager_lookup_class 属性。

21.2.6. 各种缓存提供商/缓存并发策略的兼容性

重要

没有一种缓存提供商能够支持上列的所有缓存并发策略。下表中列出了各种提供器、及其各自适用的并发策略。

没有一种缓存提供商能够支持上列的所有缓存并发策略。下表中列出了各种提供器、及其各自适用的并发策略。

表 21.2. 各种缓存提供商对缓存并发策略的支持情况(Cache Concurrency Strategy Support)

Cache read-only nonstrict-read-write read-write transactional
Hashtable (not intended for production use) yes yes yes  
EHCache yes yes yes yes
OSCache yes yes yes  
SwarmCache yes yes    
JBoss Cache 1.x yes     yes
JBoss Cache 2 yes     yes

21.3. 管理缓存(Managing the caches)

无论何时,当你给 save()update() 或 saveOrUpdate() 方法传递一个对象时,或使用load()get()list()iterate() 或 scroll() 方法获得一个对象时,该对象都将被加入到 Session 的内部缓存中。

当随后 flush() 方法被调用时,对象的状态会和数据库取得同步。如果你不希望此同步操作发生,或者你正处理大量对象、需要对有效管理内存时,你可以调用 evict() 方法,从一级缓存中去掉这些对象及其集合。

例 21.9. Explcitly evicting a cached instance from the first level cache using Session.evict()

ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set
while ( cats.next() ) {
    Cat cat = (Cat) cats.get(0);
    doSomethingWithACat(cat);
    sess.evict(cat);
}

Session 还提供了一个 contains() 方法,用来判断某个实例是否处于当前 session 的缓存中。

如若要把所有的对象从 session 缓存中彻底清除,则需要调用 Session.clear()

对于二级缓存来说,在 SessionFactory 中定义了许多方法,清除缓存中实例、整个类、集合实例或者整个集合。

例 21.10. Second-level cache eviction via SessionFactoty.evict() andSessionFacyory.evictCollection()

sessionFactory.evict(Cat.class, catId); //evict a particular Cat
sessionFactory.evict(Cat.class);  //evict all Cats
sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections

CacheMode 参数用于控制具体的 Session 如何与二级缓存进行交互。

  • CacheMode.NORMAL:从二级缓存中读、写数据。

  • CacheMode.GET:从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。

  • CacheMode.PUT:仅向二级缓存写数据,但不从二级缓存中读数据。

  • CacheMode.REFRESH:仅向二级缓存写数据,但不从二级缓存中读数据。通过hibernate.cache.use_minimal_puts 的设置,强制二级缓存从数据库中读取数据,刷新缓存内容。

如若需要查看二级缓存或查询缓存区域的内容,你可以使用统计(Statistics) API。

例 21.11. Browsing the second-level cache entries via the Statistics API

Map cacheEntries = sessionFactory.getStatistics()
        .getSecondLevelCacheStatistics(regionName)
        .getEntries();

此时,你必须手工打开统计选项。可选的,你可以让 Hibernate 更人工可读的方式维护缓存内容。

例 21.12. Enabling Hibernate statistics

hibernate.generate_statistics true
hibernate.cache.use_structured_entries true

21.4. 查询缓存(The Query Cache)

查询的结果集也可以被缓存。只有当经常使用同样的参数进行查询时,这才会有些用处。

21.4.1. 启用查询缓存

按照应用程序的事务性处理过程,查询结果的缓存将产生一些负荷。例如,如果缓存针对 Person 的查询结果,在 Person 发生了修改时,Hibernate 将需要跟踪这些结果什么时候失效。因为大多数应用程序不会从缓存查询结果中受益,所以 Hibernate 在缺省情况下将禁用缓存。要使用查询缓存,你首先需要启用查询缓存:

hibernate.cache.use_query_cache true

这个设置创建了两个新的缓存 region:

  • org.hibernate.cache.StandardQueryCache,保存缓存的查询结果

  • org.hibernate.cache.UpdateTimestampsCache,保存对可查询表的最近更新的时间戳。它们用于检验查询结果。

重要

If you configure your underlying cache implementation to use expiry or timeouts is very important that the cache timeout of the underlying cache region for the UpdateTimestampsCache be set to a higher value than the timeouts of any of the query caches. In fact, we recommend that the the UpdateTimestampsCache region not be configured for expiry at all. Note, in particular, that an LRU cache expiry policy is never appropriate.

如上面所提及的,绝大多数的查询并不能从查询缓存中受益,所以 Hibernate 默认是不进行查询缓存的。如若需要进行缓存,请调用 org.hibernate.Query.setCacheable(true)方法。这个调用会让查询在执行过程中时先从缓存中查找结果,并将自己的结果集放到缓存中去。

注意

查询缓存不会缓存缓存中实际实体的状态;它只缓存标识符值和值类型的结果。出于这个原因,对于那些作为查询结果缓存的一部分(和集合缓存一样)进行缓存的实体,查询缓存应该和二级缓存一起使用。

21.4.2. 查询缓存区

如果你要对查询缓存的失效政策进行精确的控制,你必须调用 Query.setCacheRegion() 方法,为每个查询指定其命名的缓存区域。

List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger")
        .setEntity("blogger", blogger)
        .setMaxResults(15)
        .setCacheable(true)
        .setCacheRegion("frontpages")
        .list();

如果查询需要强行刷新其查询缓存区域,那么你应该调用org.hibernate.Query.setCacheMode(CacheMode.REFRESH)方法。 这对在其他进程中修改底层数据(例如,不通过Hibernate修改数据),或对那些需要选择性更新特定查询结果集的情况特别有用。这是对org.hibernate.SessionFactory.evictQueries() 的更为有效的替代方案,同样可以清除查询缓存区域。

分享到:
评论

相关推荐

    hibernate缓存机制

    Hibernate缓存机制是提高应用程序性能的关键技术之一,它通过存储数据副本减少对物理数据库的访问。缓存可以分为两层:第一级缓存和第二级缓存。 **第一级缓存**是内置在Session中的,它是不可卸载的,也称为...

    Hibernate缓存机制

    h​i​b​e​r​n​a​t​e​缓​存​机​制​,​你​必​须​学​的​持​久​层​技​术​。

    hibernate缓存机制分析共17页.pdf.zip

    《Hibernate缓存机制详解》 Hibernate,作为Java领域中广泛使用的对象关系映射(ORM)框架,极大地简化了数据库操作。其缓存机制是优化性能的关键组成部分,它减少了对数据库的直接访问,提高了数据处理效率。本文...

    Hibernate缓存机制,转载

    **标题:“Hibernate缓存机制,转载”** **描述:**这篇博客主要探讨了Hibernate框架中的缓存机制,包括一级缓存和二级缓存的概念、工作原理以及如何在实际开发中应用。 **标签:“源码 工具”** **知识点详解:*...

    Hibernate缓存机制.txt

    Hibernate缓存机制.txt

    Hibernate缓存机制探讨.doc

    ### Hibernate缓存机制详解 #### 一、概述 Hibernate 是一款流行的 Java 持久层框架,它简化了 Java 应用程序与数据库交互的过程。然而,直接使用 JDBC 访问数据库存在一定的性能开销。为了提升性能,Hibernate ...

    Hibernate缓存机制解说

    ## Hibernate缓存机制详解 ### 一、缓存分类与管理 Hibernate提供了两种主要的缓存类型:一级缓存和二级缓存。 #### 1. 一级缓存 一级缓存也称为Session缓存,它在同一个Session中对数据的多次读取操作只需要一...

    HIBERNATE的缓存机制

    Hibernate缓存机制是提高应用程序性能的关键特性,尤其是在频繁与数据库交互的应用中。缓存通过减少对物理数据库的直接访问次数,显著提升了数据读取和写入的速度。这主要是因为从缓存中读取数据比从数据库中获取更...

    Hibernate缓存机制探讨

    在配置Hibernate缓存时,需要明确哪些实体或查询结果应该缓存,并设置相应的缓存策略。例如,我们可以使用`@Cacheable`注解标记实体类,使用`@Cache`注解来定义缓存区域和策略。同时,对于查询结果的缓存,可以使用`...

    Hibernate缓存机制深入浅出

    Hibernate缓存介于Hibernate应用和数据库之间,缓存中存放了数据库数据的拷贝。 其作用是减少访问数据库的频率,从而提高应用的运行性能

    hibernate 缓存机制

    Hibernate的缓存机制是优化应用程序性能的关键组成部分,它通过存储数据副本减少对数据库的直接访问,从而提升系统响应速度。缓存主要分为两类:一级缓存(Session缓存)和二级缓存。 一级缓存是Hibernate的核心...

    hibernate缓存

    ### Hibernate缓存机制及优化策略 #### 一、概述 Hibernate作为一款优秀的对象关系映射(ORM)框架,在Java开发领域被广泛应用于数据库操作。它提供了丰富的缓存机制来提高应用性能并降低数据库访问压力。本文将...

    Hibernate缓存,性能优化

    综上所述,Hibernate缓存机制是提升应用性能的重要手段,通过合理配置缓存策略、优化查询方式、管理数据库连接以及实施有效的监控和调优措施,可以显著提高Hibernate应用的运行效率和用户体验。然而,缓存的使用并非...

    Hibernate缓存深入详解

    Hibernate缓存机制是其性能优化的核心组成部分,对于提高应用程序的运行效率至关重要。它位于Hibernate应用和数据库之间,减少了对数据库的直接访问,通过存储数据库数据的副本来加速数据检索。 **1. Hibernate缓存...

    Hibernate缓存

    2. Hibernate缓存机制.doc:这个文档应该详细解释了Hibernate的一级和二级缓存机制,包括缓存的生命周期、更新策略(如脏检查和锁机制)以及缓存失效策略。 3. osCache.doc:可能深入介绍了Oscache的高级特性和最佳...

Global site tag (gtag.js) - Google Analytics