前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hibernate缓存配置

Hibernate缓存配置

作者头像
大道七哥
发布2019-09-10 20:52:59
1.5K0
发布2019-09-10 20:52:59
举报
文章被收录于专栏:大道七哥大道七哥

一级缓存 Hibernate的一级缓存是由Session提供的,因此它只存在于Session的生命周期中,当程序调用save(),update(),saveorupdate()等方法 及调用查询接口list,filter,iterate时,如session缓存中还不存在相应的对象,Hibernate会把该对象加入到一级缓存中, 当Session关闭的时候该Session所管理的一级缓存也会立即被清除 Hibernate的一级缓存是Session所内置的,不能被卸载,也不能进行任何配置 二级缓存配置: 1、首先要打开二级缓存,在hibernate.cfg.xml中添加如下配置: <property name="hibernate.cache.use_second_level_cache">true</property> 2、Hibernate的二级缓存使用第三方的缓存工具来实现,所以我们需要指定Hibernate使用哪个 缓存工具。如下配置指定Hibernate使用EhCache缓存工具。 <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> 3、Hibernate在默认情况下并不会对所有实体对象进行缓,所以,我们需要指定缓存哪些对象, 在实体对象的映射文件中(相应的<class>标签内部),添加如下配置: <cache usage="read-only"/> usage="read-only"是“只读”缓存策略。 注意,这个<cache>标签只能放在<class>标签的内部,而且必须处在<id>标签的前面!!! 这个<cache>标签放在哪些<class>标签下面,就说明会多这些类的对象进行缓存 4、对于第3步,有一个可选的方案是在hibernate.cfg.xml文件中指定哪些类的对象需要缓存, 而不需要使用<cache>标签来指定。如: 在hibernate.cfg.xml中添加如下配置: <class-cache class="com.bjsxt.hibernate.Classes" usage="read-only" /> 注意,这个<class-cache>标签必须放在<mapping>标签的后面!! Hibernate缓存配置 _____________________________________________________________________________________ Hibernate的缓存分为:   一级缓存:在Session级别的,在Session关闭的时候,一级缓存就失效了。   二级缓存:在SessionFactory级别的,它可以使用不同的缓存实现,如EhCache、JBossCache、OsCache等。 缓存的注释写法如下,加在Entity的java类上:   @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 缓存的方式有四种,分别为:   CacheConcurrencyStrategy.NONE   CacheConcurrencyStrategy.READ_ONLY,只读模式,在此模式下,如果对数据进行更新操作,会有异常;   CacheConcurrencyStrategy.READ_WRITE,读写模式在更新缓存的时候会把缓存里面的数据换成一个锁,其它事务如果去取相应的缓存数据,发现被锁了,直接就去数据库查询;   CacheConcurrencyStrategy.NONSTRICT_READ_WRITE,不严格的读写模式则不会的缓存数据加锁;   CacheConcurrencyStrategy.TRANSACTIONAL,事务模式指缓存支持事务,当事务回滚时,缓存也能回滚,只支持JTA环境。 另外还有如下注意事项:   1、查询缓存需要在Query的相应方法执行前加上这么一句:   query.setCacheable(true);   在使用Hibernate时,获得的query有setCacheable方法,可以设置使用缓存,但当使用JPA时,javax.persistence.Query并没有setCacheable方法,此时如果JPA的实现是Hibernate时,可以将其进行如下转化,再调用setCacheable方法(如果JPA的实现是其它ORMAP框架,就不知道怎么做了)。 if (query instanceof org.hibernate.ejb.QueryImpl) {     ((org.hibernate.ejb.QueryImpl) query).getHibernateQuery().setCacheable(true); }   2、还有就是查询缓存的查询执行后,会将查询结果放入二级缓存中,但是放入的形式是以ID为Key,实例作为一个Value。   3、hibernate的配置文件中需加入如下信息: <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" /> <property name="hibernate.cache.use_second_level_cache" value="true" /> <property name="hibernate.cache.use_query_cache" value="true" />

缓存映射(Cache mappings)

类或者集合映射的“<cache>元素”可以有下列形式:

<cache usage="transactional|read-write|nonstrict-read-write|read-only" (1)/> (1) usage说明了缓存的策略: transactional、 read-write、 nonstrict-read-write或 read-only。

另外(首选?), 你可以在hibernate.cfg.xml中指定<class-cache>和 <collection-cache> 元素。 这里的usage 属性指明了缓存并 发策略(cache concurrency strategy)。

只读 缓存(read only)

如果你的应用程序只需读取一个持久化类的实例,而无需对其修改, 那么就可以对其进行只读 缓存。这是最简单,也是实用性最好的方法。甚至在集群中,它也能完美地运作。 <class name="eg.Immutable" mutable="false"> <cache usage="read-only"/> ....</class>

读/写缓存( read/write)

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

非严格读/写缓存(nonstrict read/write)

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

------------------------------------------------------------------------- 在jBPM 中使用不少这样的非严格读/写缓存的处理: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping default-access="field"> <class name="org.jbpm.context.def.VariableAccess" table="JBPM_VARIABLEACCESS" lazy="false"> <cache usage="nonstrict-read-write"/> <id name="id" column="ID_"><generator class="native" /></id> <property name="variableName" column="VARIABLENAME_" /> <property name="access" column="ACCESS_" /> <property name="mappedName" column="MAPPEDNAME_" /> </class> </hibernate-mapping>

它的ehcache.xml 是这样配置的: <ehcache> <defaultCache maxElementsInMemory="100000" eternal="true" overflowToDisk="false" diskPersistent="false" /> </ehcache> Hibernate Annotation 中配置EhCache缓存

1. 首先设置EhCache,建立配置文件ehcache.xml,默认的位置在class-path,可以放到你的src目录下:

1.xml version="1.0" encoding="UTF-8"?> 2.<ehcache> 3. <diskStore path="java.io.tmpdir"/> 4.  <defaultCache 5.   maxElementsInMemory="10000" 6.   eternal="false" 7. 8.   overflowToDisk="true" 9. 10.   timeToIdleSeconds="300" 11.   timeToLiveSeconds="180" 12.   diskPersistent="false" 13.   diskExpiryThreadIntervalSeconds= "120"/> 14.ehcache>

2. 在Hibernate配置文件中设置:

<hibernate-configuration><session-factory>……<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property><property name="cache.use_second_level_cache">true</property>……</session-factory></hibernate-configuration> 此外,可以把cache.use_second_level_cache设置为false关闭所有的hibernate二级缓存。但此属性对指定<cache>的类缺省为true。

3. 为了使用二级缓存,需要在每一个Hibernate Entity上配置。

1.@Entity 2.@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 3.public class Forest { ... }

1.@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) 2.@JoinColumn(name="CUST_ID") 3.@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 4.public SortedSet getTickets() { 5. return tickets; 6.}

1.@Cache( 2. CacheConcurrencyStrategy usage(); (1) 3. String region() default ""; (2) 4. String include() default "all"; (3) 5.)

(1) usage: 提供缓存对象的事务隔离机制,可选值有以下几种 (NONE, READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL) (2) region (optional): 指定缓存的区域,默认是类的全限定名。利用缓存区域,可以更精确的指定每个区域的缓存超前策略。如果指定了缓存区域前缀(在hibernate.cfg.xml中设置cache.region_prefix属性为一个字符串),则所有的缓存区域名前将加上这个前缀。 (3) include (optional): all to include all properties, non-lazy to only include non lazy properties (default all). 如果不是使用annotation的话,则是在Hbm文件中添加cache usage="read-only"


-END-

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2014-12-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档