怎样对从ehcache分布式缓存缓存中取出的对象修改而不改变缓存中的对象

使用EhCache将对象put进缓存后,get出来为null的问题
时间: 11:23:35
&&&& 阅读:789
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&
使用EhCache将对象put进缓存后,get出来为null的问题
以前使用EhCache缓存数据的时候,保存的value都是基于Java的基础类型数据,最近发现保存自定义类型的对象时,get()出来的Element要么为null,要么当用Element的getValue()时抛出net.sf.ehcache.CacheException: Value xxx is not Serializable异常。
EhCache在put对象时,该对象必须是可序列化(Serializable)的类型,也就是说要实现java.io.Serializable。因为EhCache在put对象时,是序列化保存的。 官方文档对EhCache put方法的:
void put(Element element)throws IllegalArgumentException,IllegalStateException,CacheException Put an element in the cache. Resets the access statistics on the element, which would be the case if it has previously been gotten from a cache, and is now being put back.
Also notifies the CacheEventListener that:
the element was put, but only if the Element was actually put. if the element exists in the cache, that an update has occurred, even if the element would be expired if it was requested Parameters: element - An object. If Serializable it can fully participate in replication and the DiskStore.
Throws: IllegalStateException - if the cache is not Status.STATUS_ALIVE IllegalArgumentException - if the element is null CacheException
另外:EhCache的flush()方法是将缓存序列化到文件中, 缓存配置diskPersistent=“true"时有用。如果put没有序列化的对象后再flush(),从Cache中get()将得到null(不支持序列化对象,没法持久化到文件中)。如果put后没有flush(),则可以get()到缓存的Element,但是当调用Element的getValue()取缓存对象时,会报net.sf.ehcache.CacheException: Value xxx is not Serializable异常。标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:http://my.oschina.net/u/1010578/blog/389683
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!&&&&&&&&&&&&Hibernate缓存-使用Ehcache让实体对象集合对象缓存
正在努力加载播放器,请稍等…
正在努力加载播放器
大小:555.28KB&&所需金币:50
&& & 金币不足怎么办?
下载量:-次 浏览量:280次
贡献时间: 18:30:00
文档标签:
已有-位用户参与评分
同类热门文档
你可能喜欢
看过这篇文档的还看过
阅读:223&&下载:0
阅读:257&&下载:0
阅读:76&&下载:0
阅读:65&&下载:0
阅读:379&&下载:0
阅读:418&&下载:0
阅读:126&&下载:0
阅读:116&&下载:0
阅读:184&&下载:0
阅读:112&&下载:0
该用户的其他文档
所需财富值:
50文件大小:555.28KB
您当前剩余财富值:&&
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
举报该文档侵犯版权。
例: /help.shtml之前一直感觉缓存是高上大的东西,没有心思去研究。做了之后发现,简单的使用还是很容易的。这里记录ehcache在jfinal中的简单使用。
1.ehcahe简介
EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。
看到官网上已经3.0了。
我把它当做一个可以存储数据和读取数据的存在。缓存其实就一个key-value的数据存储工具。目前我使用过两个方面。
一是缓存数据库的数据。
都说连接数据库的开销很大,所以对数据变化较小的一部分可以缓存起来,下次直接从缓存中取数据。(关于数据的安全性未曾考虑)。
二是存储变量。
在web后端开发过程中,有些数据需要保存起来方便下次使用。比如短信的验证码。我之前都是在类中添加一个map类变量,然后存入map,下次取出或者销毁。这样做事可以的,类实例化后。类变量就加载到内存中了,可以存储数据。但有个问题,关于类的创建和销毁的声明周期问题。不能确保他什么时候去销毁。或者说,这一块我了解有限,还没研究到。
因此,放到缓存中就可以了。缓存可以设置数据的大小,失效时间。
3.用到的两个基本实现
1 &?xml version="1.0" encoding="UTF-8"?&
2 &ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="false" monitoring="autodetect"
dynamicConfig="true"&
&diskStore path="java.io.tmpdir"/&
&defaultCache
maxEntriesLocalHeap="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="20"
timeToLiveSeconds="60"&
&/defaultCache&
&!-- 内存中最多可以缓存1000个element,超出1000的,不输出到磁盘中。缓存是永久有效的
name:cache唯一标识
maxElementsInMemory:内存中最大缓存对象数
eternal:Element是否永久有效,一但设置了,timeout将不起作用。
verflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。
默认策略是LRU(最近最少使用)。还可以设置为FIFO(先进先出)或是LFU(较少使用)。
&cache name="zone"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"
内存中最多可缓存10000个Element,其中的element会在闲置5分钟或是存活10分钟之后失效。
If there are more than 10000 elements it will overflow to the
disk cache, which in this configuration will go to wherever java.io.tmp is
defined on your system. On a standard Linux system this will be /tmp"
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
transactionalMode="off" 使ehcache作为JTA事务的参与者maxEntriesLocalHeap:堆内存中最大缓存对象数,0没有限制Sets the maximum number of objects that will be held on heap memory. &0 = no limit.maxEntriesLocalDisk:磁盘中的最大对象数,默认为0不限制Sets the maximum number of objects that will be maintained in the DiskStoreThe default value is zero, meaning unlimited.
&cache name="mobileMsg"
maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000"
eternal="false"
overflowToDisk="true"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off"
54 &/ehcache&
3.1追加使用的问题:
从cache取出的对象默认会
copyOnRead="false"
copyOnWrite="false".如果对取出的对象操作,就会修改cache中的对象。因为序列化问题。因此,如果想要对缓存的数据修改而不改变缓存中的原始数据,应该将这两个设为true。
4.在jfinal中的使用
jfinal框架集成了ehcache,只要简单配置就可以使用了。配置如下:
4.1在commonconfig中添加插件:
1 @Override
public void configPlugin(Plugins me) {
me.add(new EhCachePlugin());
4.2.通过CacheKit管理缓存
上面的配置可以看出,一个缓存(姑且这么叫)由一个name字段唯一标识,数据又是key-value,因此,只有name-key就可以唯一标识value.
4.2.1将变量加入缓存:
1 CacheKit.put(cacheName, key, value);
cacheName:在xml中配置的缓存name字段
key:唯一标识
value:你要存储的对象,value可以是任何对象、数据类型,比如person,map,list等
1 CacheKit.get(cacheName, key);
4.3findByCache中使用
这个直接使用就是加入缓存了。
1 Db.findByCache(cacheName, key, sql);
ehcache基本原理
ehcache是一个用实现的使用简单,高速,实现线程安全的缓存管理类库,ehcache提供了用内存,磁盘,以及存储方式等多种灵活的cache管理方案。同时ehcache作为开放,采用限制比较宽松的Apache License V2.0作为授权方式,被广泛地用于Hibernate,&&Spring,Cocoon等其他。
Ehcache的类层次模型主要为三层,最上层的是CacheManager,他是操作Ehcache的入口。我们可以通过CacheManager.getInstance()获得一个单个的CacheManager,或者通过CacheManager的构造函数创建一个新的CacheManager。每个CacheManager都管理着多个Cache。而每个Cache都以一种类Hash的方式,关联着多个Elemenat。而Element则是我们用于存放要缓存内容的地方。
ehcache的刷新策略ehcache的刷新策略是当缓存在放入的时候记录一个放入时间,它是用Lazy Evict的方式,在取的时候同设置的TTL比较
ehcache缓存的3种清空策略:1 FIFO,先进先出2 LFU,最少被使用,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。3 LRU,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
事件处理可以为CacheManager添加事件监听,当对CacheManager增删Cache时,事件处理器将会得到通知。要配置事件处理,需要通过ehcache的配置文件来完成。可以为Cache添加事件监听,当对Cache增删Element时,事件处理器将会得到通知。要配置事件处理,需要通过ehcache的配置文件来完成。
ehcache参数配置:maxInMemory - 设定内存中创建对象的最大值。eternal - 设置元素(译注:内存中对象)是否永久驻留。如果是,将忽略超时限制且元素永不消亡。timeToIdleSeconds - 设置某个元素消亡前的停顿时间。也就是在一个元素消亡之前,两次访问时间的最大时间间隔值。这只能在元素不是永久驻留时有效(译注:如果对象永恒不灭,则设置该属性也无用)。如果该值是 0 就意味着元素可以停顿无穷长的时间。timeToLiveSeconds - 为元素设置消亡前的生存时间。也就是一个元素从构建到消亡的最大时间间隔值。这只能在元素不是永久驻留时有效。overflowToDisk&&- 设置当内存中缓存达到maxInMemory 限制时元素是否可写到磁盘上。
1.&&&&&&&ehcache使用了edHashMap来存放Element。jdk要1.5以上。Ehcache1.5可以使用jdk1.4
如果在添加Elemtent时,缓存中的Element个数达到了最大缓存数并且overflowToDisk配置的属性为true,Ehcache会更具配置项MemoryStoreEvictionPolicy的失效策略将Element输出到磁盘。如果overflowToDisk为fasle,Ehcache将删除内存中Element
值得注意的是缓存中失效的Element并不会别马上清理掉,所以想得到内存的真实大小应该调用方法calculateInMemorySize()方法。
一个ehcache.对应一个CacheManager
不同的缓存应该对应不同的硬盘上的路径,否则会报错
注意要想使用磁盘缓存,缓存的Element必须实现序列化接口。否则会抛出异常。
Ehcache会将每个缓存配置的文件路径下创建一个cache_name.data文件,如果使用的磁盘持久化技术,还会生成一个cache name.index文件。
8.&&&&&&&Ehcache有一个后台线程专门做Ellment失效监测以及清除工作。设置线程运行间隔时间,可通过设置diskExpiryThreadIntervalSeconds属性来完成,此值不宜设置过低,否则会导致清理线程占用大量CPU。默认值是120秒。
9.&&&&&&&持久化可在Element的diskPersistent配置项中配置,如果配置为&false&或是&omitted&在CacheManager shutdown或是startup后,用来缓存Element的文件将被清除掉。如果设置为&true&,data和index文件会被保存下来,对于新创建的CacheManager Element也是可用的。
使用时必须显示调用cache. Flush()才会将缓存到磁盘中。
磁盘缓存步骤:从MemoryStore中把没有失效的Element刷新到DiskStore,Element被写入到data文件,Element将被序列化到index文件。
12.&&&磁盘缓存大小默认是没有限制的,不过可通过maxElementsOnDisk来指定。当磁盘缓存达到maxElementsOnDisk指定的值时,Ehcache会清理磁盘中的缓存使用默认策略是LFU(使用频率最低)。
13.&&&在使用完Ehcache后,必须要shutdown缓存。Ehcache中有自己的关闭机制,不过最好在你的代码中显示调用CacheManager.getInstance().shutdown();
14.&&&Cache:对于getValue()能取到可序列化的值;getObjectValue()取得非序列化的值
15.&&&cache.getSize();得到缓存中元素的个数;获得当前MemoryStore中的element数量:cache.getMemoryStoreSize();获得当前DiskStore中element数量:cache.getDiskStoreSize();
16.&&&在使用完Ehcache后,必须要shutdown缓存。Ehcache中有自己的关闭机制,不过最好在你的代码中显示调用CacheManager.getInstance().shutdown();
17.&&&ehcache-core-1.6&1.7没有任何依赖;ehcache1.7.1依赖SLF4J,以及相应的log的jar包。
18.&&&CacheManager可以通过单例(factory的静态方法)或者构造函数(constructors)创建。分别叫做single model和instance model。当两种情况都有的时候,系统会采用单例模式,构造器每次都生成单例模式
19.&&&对于想存储数据到硬盘,或者集群时复制到其他缓存区域的数据,必须可序列化。如果不可序列化,该数据在进行上述操作时会被丢弃,且没有报错,只是在debug级别有日志信息。
20.&&&读取cache的数据,有以下几种方式:
Cache-aside:&直接操作数据
Cache-as-sor:read-through、write-through和write-behind的结合
Read-through:
Write-through:
Write-behind:
21.&&&从ehcache2.0开始,以下属性可以在运行时改变:
& timeToLive
& timeToIdle
& maxElementsInMemory
& maxElementsOnDisk
& memory store eviciton policy
& CacheEventListeners can be added and removed dynamically []
&&&当eternal属性为&true&时,timeToLive和timeToIdle会失效
22.&&&以下代码演示怎么运行时修改缓存属性
This example shows how to dynamically modify the cache configuration of an already running cache:
Cache cache = manager.getCache("sampleCache");
CacheConfiguration config = cache.getCacheConfiguration();
config.setTimeToIdleSeconds(60);
config.setTimeToLiveSeconds(120);
config.setMaxElementsInMemory(10000);
config.setMaxElementsOnDisk(1000000);
Dynamic cache configurations can also be frozen to prevent future changes:
Cache cache = manager.getCache("sampleCache");
cache.disableDynamicFeatures();
23.&&&2.5之前是通过元素的个数来表示内存或者硬盘的大小;2.5之后,通过字节数来表示。2.5暂时还没有出来。新属性将会是:
The new cache attributes are:
& maxBytesOnHeap
& maxBytesOffHeap (formerly maxMemoryOffHeap)
& maxBytesOnDisk
甚至,还可以指定比例,如:maxBytesOnHeap="20%".
24.&&&Ehcache可以将一些数据一直放到缓存或者堆栈或者硬盘或者terracotta的L2中。主要是为了满足Hibernate等一些情况下的需求。但是,这样很容易造成内存溢出的错误
25.&&&当缓存刚启动时,ehcache提供一个机制可以先加载数据:BootstrapCacheLoader
class=".sf.ehcache.distribution.jgroups.JGroupsBootstrapCacheLoaderFactory"
properties="bootstrapAsynchronously=true"/&
DiskStoreBootstrapCacheLoaderFactory:从硬盘加载数据到堆栈
class="net.sf.ehcache.store.DiskStoreBootstrapCacheLoaderFactory"
properties="bootstrapAsynchronously=true"/&
TerracottaBootstrapCacheLoaderFactory:从terracotta的L2中加载数据
class="net.sf.ehcache.store.TerracottaStoreBootstrapCacheLoaderFactory"
properties="bootstrapAsynchronously=true"/&
26.&&&可以配置ehcache在读或者写的时候,做些事情。
CacheConfiguration config = new CacheConfiguration("copyCache", 1000).copyOnRead(true)
Cache copyCache = new Cache(config);
&&&&默认此属性是false。
maxElementsInMemory="10"
eternal="false"
timeToIdleSeconds="5"
timeToLiveSeconds="10"
overflowToDisk="false"
copyOnRead="true"
copyOnWrite="true"&
pany.ehcache.MyCopyStrategy"/&
27.&&&每一个cache都有一个copyStrategy,所以,该实现是要求线程安全的
在ehcache启动的时候,可以设置缓存失效。命令行启动的时候如下:
java -Dnet.sf.ehcache.disabled=true
其他特殊的系统属性:
1)java -Dnet.sf.ehcache.use.classic.lru=true
当LRU被选中的时候,更老的LruMemoryStore实现策略将会被真正采用
28.&&&ehcache.xml必须遵守ehcache.xsd文件中的要求
29.&&&当无参的构造函数,或者静态构造方法被调用的时候,系统会在最顶层的classpath路径下找名叫ehcache.xml的配置文件,如果查找失败,会以jar包中的ehcache-failsafe.xml文件(里边的缓存配置极其简单)替代。同时,一个警告会提醒建立自己的配置文件。
30.&&&Update checker可以检查是否有最新的ehcache版本。有两个办法可以去掉该功能:
1)通过系统参数:-Dnet.sf.ehcache.skipUpdateCheck=true
2)通过配置文件:
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="false" monitoring="autodetect"
dynamicConfig="true"&
31.&&&Ehcache1.6之前只支持ASCII编码,之后,UTF-8也被支持。但UTF-8比ASCII更多落后,所以没必要做专门的转换
32.&&&每一个Cachemanager应该有自己的独有的ehcache.xml配置文件。因为,当共用时,硬盘缓存路径或者监听端口将会冲突。系统也会发出警告,提醒用户配置专门的配置文件为每一个cachemanager.在分布式系统中,ehcache.xml应该配置成一样的。
33.&&&Ehcache有3个存储:
1)&内存存储
2)&非堆存储(大内存,企业ehcache才拥有)
3)&硬盘存储(两个版本:开源的和企业级ehcache)
34.&&&内存存储
其本质是使用java的LinkedHashMap来实现的。安全、内存管理安全、速度快
35.&&&calculateInMemorySize()可以用来计算当前ehcache内存占用大小。但生产线上不应该使用,因为这个功能效率非常低
36.&&&同时,ehcache内部有一个低等级的进程,它会判断元素的是否过期。diskExpiryThreadIntervalSeconds属性可以设置该线程执行的间隔时间(默认是120秒,不能太小,以免影响效率).
37.&&&非堆存储
Terracotta BigMemory是一个新增的功能,它允许系统占用堆以外的内存,速度是硬盘存储的100倍,允许很大的存储被创建(350G被测试过)
因为非堆数据是以字节流的形式存储,所以要求Element的key和value都要是可以序列化的。
因为序列化和反序列化的过程,这种存储形式比内存存储慢10倍
38.&&&硬盘存储
线程安全的
39.&&&当maxElementsOnDisk被设置的时候,硬盘上的存储达到限制时,LFU会被执行用于清除数据,只能是该算法,不可配置
40.&&&Persistence被设置成false或者omitted,当系统重启时,不会硬盘的数据存储在硬盘上,.data文件将会被删除.相反,.data文件不会被删除,下次重启后Cachemanager还可以使用.data文件。
41.&&&虚拟机被停止的时候,强烈建议调用Cachemanager.shutdown()方法。
42.&&&在关闭java虚拟机时,系统执行以下步骤:
Considerations for guidance on how to safely shut the Virtual Machine down.
When a DiskStore is persisted, the following steps take place:
& Any non-expired Elements of the MemoryStore are flushed to the DiskStore
& Elements awaiting spooling are spooled to the data file
& The free list and element list are serialized to the index file
On startup the following steps take place:
& An attempt is made to read the index file. If it does not exist or cannot be read successfully, due to disk corruption, upgrade of ehcache, change in JDK version etc, then the data file is deleted and the DiskStore starts with no Elements in it.
& If the index file is read successfully, the free list and element list are loaded into memory. Once this is done, the index file contents are removed. This way, if there is a dirty shutdown, when restarted, Ehcache will delete the dirt index and data files.
& The DiskStore starts. All data is available.
& The expiry thread starts. It will delete Elements which have expired.
43.&&&一个示范性地配置:
把一个拥有8G机器内存的存储分配成各种存储。设想有一个7G的数据集,共7M个元素,每个元素1k大小。
我们设置1G的堆存储和7G的非堆存储:
java -Xms1G -Xmx1G -XX:maxDirectMemorySize=7G
对应的配置文件为:
maxElementsInMemory=100
overflowToOffHeap="true"(企业)
maxMemoryOffHeap="7G"
44.&&&对于第二种集群方法,以下被测试过:
& Glassfish V2/V3
& Tomcat 6
Tomcat 6通过了所有的继集成测试
支持Weblogic10.3.2,但是SOAP不兼容。
45.&&&最大的Ehcache单实例在内存中可以缓存20GB,最大的磁盘可以缓存100GB
46.&&&关于ehcache server的相关命令用法在user guide的178页
缓存属性:
缓存配置。
以下属性是必须的:
name&-&cache的标识符,在一个CacheManager中必须唯一
maxElementsInMemory&-&在内存中缓存的element的最大数目
maxElementsOnDisk&-&在磁盘上缓存的element的最大数目
eternal&-&设定缓存的elements是否有有效期。如果为true,timeouts属性被忽略
overflowToDisk&-&设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上
以下属性是可选的:
timeToIdleSeconds&-&缓存element在过期前的空闲时间。默认为0,表示可空闲无限时间. (如果指定了这个时间,是否在被hit的前超过了这个时间就会被remove?在内存缓存数目超限之前不会被remove)
timeToLiveSeconds&-&缓存element的有效生命期。这个类似于timeouts,默认为0,不过期(是否通常情况下应该大于等于timeToIdleSeconds,小于会如何?idle时间也会减小和这个数值一样)
diskPersistent&-&在VM重启的时候是否持久化磁盘缓存,默认是false。
(测试一下true的情况?重载vm的时候会从磁盘进行序列化到对象)
diskExpiryThreadIntervalSeconds&-&磁盘缓存的清理线程运行间隔,默认是120秒. &(测试一下0的时候会如何)
memoryStoreEvictionPolicy&-&当内存缓存达到最大,有新的element加入的时候,移除缓存中element的策略。默认是LRU,可选的有LFU和FIFO可对缓存中的element配置诸如监听器和加载器。Ehcahe内建了一些
*cacheEventListenerFactory&-&监听缓存中element的put,&remove,&update和expire事件
*bootstrapCacheLoaderFactory&-&启动时加载缓存的element每个用来做分布式缓存都必须设定element的事件监听器,用来在各个CacheManager节点复制消息。
Ehcache内建了基于RMI的实现&-&RMICacheReplicatorFactory
阅读(...) 评论()博客分类:
一、Ehcache简介
&&&&& EhCache是Hibernate的二级缓存技术之一,可以把查询出来的数据存储在内存或者磁盘,节省下次同样查询语句再次查询数据库,大幅减轻数据库压力;
&&&&& 当用Hibernate对关系型数据库表进行更改时(DELETE/UPDATE),这时EhCache会自动把缓存中关于此表的所有缓存全部删除掉,以此来达到同步效果。基于这一点来说,ehcache不适合那种经常修改数据库表的情形。
&&&&& Ehcache适用场合:
1)对数据库表很少修改;
2)对并发要求不是很严格。
&&&&& 对于工业传感器实时数据,程序对其保存后,利用二级缓存技术查看历史数据。我本人也是基于这种场景才用ehcache的
二、准备工作
[list]
ehcache-core.jar ehcache核心包,在maven项目中,类似于如下引入
&dependency&
&groupId&net.sf.ehcache&/groupId&
&artifactId&ehcache-core&/artifactId&
&version&2.4.3&/version&
&/dependency&
ehcache-spring-annotations 基于spring注解ehcache,在maven项目中,类似于如下引入
&groupId&com.googlecode.ehcache-spring-annotations&/groupId&
&artifactId&ehcache-spring-annotations&/artifactId&
&version&1.1.2&/version&
&type&jar&/type&
&scope&compile&/scope&
&/dependency&
其他jar包(例如hibernate系列、spring web系列,commons系列)
[/list]
三、Ehcache.xml配置
&&&&& Ehcache.xml文件时ehcache二级缓存最主要的我配置文件,它定义了对哪些实体对象进行缓存,以及缓存策略,直接上一个配置片段把
&?xml version="1.0" encoding="UTF-8"?&
&cache name="entity.HistoryData"
maxElementsInMemory="5000" eternal="false" timeToIdleSeconds="300"
timeToLiveSeconds="7200" overflowToDisk="false" /&
&/ehcache&
name要缓存的实体类的名称
maxElementsInMemory设置该缓存实体的最大个数
eternal对象是否永久有效
timeToIdleSeconds设置对象在失效前的允许闲置时间(单位:s)
timeToLiveSeconds设置对象在失效前允许存活时间(单位:s)
overflowToDisk当缓存中对象达到maxElementsInMemory时,存入磁盘
diskSpoolBufferSizeMB设置磁盘缓冲区大小
maxElementsOnDisk设置磁盘能缓存最大对象个数
diskPersistent是否缓存虚拟机重启期数
diskExpiryThreadIntervalSeconds磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。&
clearOnFlush内存数量最大时是否清除。
两个问题:
该文件放置在那里?该文件可以放置在工程的任意位置
该文件如何引入?或者说ehcache.xml路径是如何确定的?
&&& 我们可以通过查阅相关源码,可知
在hibernate.cache.provider所指定的类net.sf.ehcache.hibernate.EhCacheRegionFactory类的抽象类AbstractEhcacheRegionFactory中,对NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME中有明确的解释:
The Hibernate system property specifying the location of the ehcache configuration file name.
If not set, ehcache.xml will be looked for in the root of the classpath.
If set to say ehcache-1.xml, ehcache-1.xml will be looked for in the root of the classpath.
[/list]
四、集成到spring
&&&&& 这一个步骤分为两部分,一部分是对ehcache打开注解功能,另一部分是集成hibernate sesionFactory中
[list]
配置注解,新建spring-ehcache.xml,并在web.xml param中引入,如下:
&?xml version="1.0" encoding="UTF-8"?&
&beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ehcache="http://ehcache-spring-/svn/schema/ehcache-spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://ehcache-spring-/svn/schema/ehcache-spring http://ehcache-spring-/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd"&
&ehcache:annotation-driven /&
&bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"&
&property name="configLocation" value="classpath:ehcache.xml" /&
&ehcache:config cache-manager="cacheManager"/&
&/beans&
注:对于命名空间,前提是引入ehcache-spring-annotations.jar包,否则提示无法解析该命名空间。ConfigLocation指定ehcache.xml配置文件所在的路径。
hibernate sessionFactory配置,新建spring-sessionFactory.xml,并在web.xml中引入,如下
&?xml version="1.0" encoding="utf-8"?&
&beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang" xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"&
&context:property-placeholder location="classpath:/resource.properties" /&
&bean id="dataSource" class="com.mchange.boPooledDataSource" destroy-method="close"&
&property name="driverClass" value="${jdbc.driverClassName}"/&
&property name="jdbcUrl" value="${jdbc.url}"/&
&property name="user" value="${jdbc.username}"/&
&property name="password" value="${jdbc.password}"/&
&property name="idleConnectionTestPeriod" value="120"/&
&bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"&
&property name="dataSource" ref="dataSource"/&
&property name="schemaUpdate" value="${hibernate.schemaUpdate}"/&
&property name="packagesToScan" value="${hibernate.packageScan}"/&
&property name="hibernateProperties"&
hibernate.dialect ${hibernate.dialect}
hibernate.show_sql ${hibernate.show_sql}
hibernate.cache.region.factory_class ${hibernate.cache.provider}
hibernate.cache.use_second_level_cache ${hiberante.second.cache}
[color=red]Hibernate.cache.use_query_cache true [/color]
&/property&
&/beans&
其中,
hibernate.cache.provider 选择二级缓存实现的类
Hibernate.cache.use_second_level_cache:选择是否开启二级缓存
Hibernate.cache.use_query_cache 是否开启查询缓存(重要,后面讲到)
[/list]
五、测试
新建一个实体类
import java.io.S
import java.util.D
import javax.persistence.C
import javax.persistence.E
import javax.persistence.GeneratedV
import javax.persistence.Id;
import javax.persistence.T
import org.hibernate.annotations.C
import org.hibernate.annotations.CacheConcurrencyS
@Table(name="history_data")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class HistoryData implements Serializable{
}
把这个类映射到数据库表中。并且设置缓存方式
缓存方式有四种
参考资料 写道CacheConcurrencyStrategy.NONE
   CacheConcurrencyStrategy.READ_ONLY ,只读模式,在此模式下,如果对数据进行更新操作,会有异常;
   CacheConcurrencyStrategy.READ_WRITE ,读写模式在更新缓存的时候会把缓存里面的数据换成一个锁,其它事务如果去取相应的缓存数据,发现被锁了,直接就去数据库查询;
   CacheConcurrencyStrategy.NONSTRICT_READ_WRITE ,不严格的读写模式则不会的缓存数据加锁;
   CacheConcurrencyStrategy.TRANSACTIONAL ,事务模式指缓存支持事务,当事务回滚时,缓存也能回滚,只支持 JTA 环境。
缓存的注释写法如下,加在 Entity 的 java 类上:
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
&&& 如果我们要对hql查询设置缓存,可以通过设置this.getHibernateTemplate().setCacheQueries(boolean)来实现,前提是开启查询缓存。下面是一个例子:
public List&HistoryData& list(String name,String location,Date startTime,
Date endTime, boolean alarm,int start,int limit){
String hql = "from HistoryData hd where 1=1 ";
if(StringUtils.isNotBlank(name)){
hql+= " and hd.name like '%"+name+"%' ";
if(StringUtils.isNotBlank(location)){
hql+= " and hd.location like '"+location+"' ";
this.getHibernateTemplate().setCacheQueries(true);
List&HistoryData& hds =
this.findByNamedParam(hql, null, null, start, limit);
this.getHibernateTemplate().setCacheQueries(false);
调用这个方法,针对同一sql来讲,只发送一条sql,下次查询直接从缓存中获取。
注:this.getHibernateTemplate().setCacheQueries(true);后最好是要this.getHibernateTemplate().setCacheQueries(false),来关闭查询缓存,因为实际应用中,不可能所有的查询我们都得设置缓存。
从百草园到三味书屋
浏览: 35138 次
来自: 杭州
这个方法也不错,有兴趣换工作不?
public void writeFileToResponse ...
我这样写ok了public void writeFileToR ...
hemin108 写道还是不行··那么兄弟,那你找到其他的解决 ...
还是不行··
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 ehcache设置缓存时间 的文章

 

随机推荐