EhCache缓存学习
在看hibernate的官方文档时,看到关于缓存的介绍。
hibernate在缓存管理上做的很好,具体使用,本章不做讲解,本篇主要研究EhCache的用法。其中hibernate使用到的缓存提供商列表如下:
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.) |
其中,我对EHCache比较感兴趣。看它支持的类型包括对内存,硬盘,传统,集群都支持。
我们可以单独研究一下Ehcache缓存的使用,这样方便以后我们对其他使用到缓存的地方进行缓存的自定义管理(不单单在hibernate查询数据方面)。
ehcache下载地址: http://sourceforge.net/projects/ehcache/files/ehcache/
先写个例子,看看它的api如何使用:
EhcacheTest
- package org.base.cache.test;
- import java.net.MalformedURLException;
- import java.net.URL;
- import net.sf.ehcache.Cache;
- import net.sf.ehcache.CacheManager;
- import net.sf.ehcache.Element;
- import net.sf.ehcache.config.CacheConfiguration;
- import net.sf.ehcache.config.Configuration;
- /**
- * Ehcache缓存管理的api测试小例子
- * @author blossom
- *
- */
- public class EhcacheTest {
- /**
- * @param args
- */
- public static void main(String[] args) throws MalformedURLException {
- net.sf.ehcache.config.Configuration config=new Configuration();
- //如果不使用ehcache.xml配置文件,那么必须用代码配置一个defaultCacheConfiguration
- CacheConfiguration defaultCacheConfiguration=new CacheConfiguration();
- defaultCacheConfiguration.setMaxEntriesLocalHeap(0);
- defaultCacheConfiguration.setEternal(false);
- defaultCacheConfiguration.setTimeToIdleSeconds(30);
- defaultCacheConfiguration.setTimeToLiveSeconds(30);
- config.addDefaultCache(defaultCacheConfiguration);//设置默认cache
- net.sf.ehcache.CacheManager cacheManager=CacheManager.create(config);
- //创建缓存信息
- /*构造方法有多种,详见文档
- public Cache(String name,
- int maxElementsInMemory,
- boolean overflowToDisk,
- boolean eternal,
- long timeToLiveSeconds,
- long timeToIdleSeconds)
- */
- //自定义配置缓存
- net.sf.ehcache.Cache cache1=new Cache("mycache-one", 1000, false, false, 30, 30);
- cacheManager.addCache(cache1);
- //只有配置了defaultCacheConfiguration,这个方法才可以使用。因为用字符串命名的缓存必须有实际配置。
- cacheManager.addCache("mycache-two");//添加一个空缓存
- //往缓存中放值
- String objkey1="key1",objvalue1="value1";
- cache1.put(new Element(objkey1,objvalue1));//直接放
- //遍历取出某个缓存中的所有值
- if(cacheManager.getCache("mycache-one")!=null){
- Cache cache11=cacheManager.getCache("mycache-one");
- if(cache11.getKeys().size()==0){
- System.out.println("mycache-one exits,but no value.");
- }else{
- for(int i=0;i<cache11.getKeys().size();i++){
- Object thekey=cache11.getKeys().get(i);
- Object thevalue=cache11.get(thekey);
- System.out.println("mycache-one-"+i+",key:"+thekey.toString()+",value:"+thevalue.toString());
- }
- }
- }else{
- System.out.println("mycache-one-is null");
- }
- /*打印
- mycache-one-0,key:key1,value:[ key = key1, value=value1, version=1, hitCount=1, CreationTime = 1366263629054, LastAccessTime = 1366263629054 ]
- */
- if(cacheManager.getCache("mycache-two")!=null){
- Cache cache2=cacheManager.getCache("mycache-two");
- if(cache2.getKeys().size()==0){
- System.out.println("mycache-two exits,but no value.");
- }else{
- for(int i=0;i<cache2.getKeys().size();i++){
- Object thekey=cache2.getKeys().get(i);
- Object thevalue=cache2.get(thekey);
- System.out.println("mycache-two-"+i+",key:"+thekey.toString()+",value:"+thevalue.toString());
- }
- }
- }else{
- System.out.println("mycache-two-is null");
- }
- /*打印
- mycache-two exits,but no value.
- */
- }
- }
Ehcache在使用的大多数情况,是用ehcache.xml来配置的。在spring中的集成很方便。
下面我们使用ehcache.xml,但不在web环境下,对缓存进行自定义。
org/base/cache/test/myehcache.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="ehcache.xsd"
- updateCheck="true" monitoring="autodetect"
- dynamicConfig="true">
- <diskStore path="java.io.tmpdir"/>
- <!-- JTA事务配置。class属性若为空,则默认会按照一个顺序寻找TransactionManager对象。
- 也可以自定义,需要实现接口net.sf.ehcache.transaction.manager.TransactionManagerLookup
- -->
- <!--
- <transactionManagerLookup class="net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup"
- properties="jndiName=java:/TransactionManager" propertySeparator=";"/>
- -->
- <!-- CacheManagerEventListener 缓存监听,根据需要自定义监听类
- <cacheManagerEventListenerFactory class="" properties=""/>
- -->
- <!-- Terracotta服务器集群配置,详细看文档 -->
- <!--
- <terracottaConfig url="localhost:9510"/>
- -->
- <defaultCache
- maxEntriesLocalHeap="0"
- eternal="false"
- timeToIdleSeconds="30"
- timeToLiveSeconds="30">
- <!-- <terracotta/>-->
- </defaultCache>
- <!--
- 缓存名为myCache1,
- 这个缓存最多包含10000个元素在内存中,并将
- 闲置超过5分钟和存在超过10分钟的元素释放。
- 如果超过10000元素,将溢流到磁盘缓存,并且硬盘缓存最大数量是1000.
- 硬盘路径是定义的java.io.tmp。
- -->
- <cache name="myCache1"
- maxEntriesLocalHeap="500"
- maxEntriesLocalDisk="1000"
- eternal="false"
- diskSpoolBufferSizeMB="20"
- timeToIdleSeconds="300"
- timeToLiveSeconds="600"
- memoryStoreEvictionPolicy="LFU"
- transactionalMode="off">
- <persistence strategy="localTempSwap"/>
- </cache>
- <!--
- 缓存名为sampleCache2。
- 此缓存在内存中最大元素的数量是1000。
- 没有设置溢出到磁盘,所以1000就是这个缓存的最大值。
- 注意,当一个缓存eternal设置成true,那么TimeToLive
- 和timeToIdle江不起作用。
- <cache name="sampleCache2"
- maxEntriesLocalHeap="1000"
- eternal="true"
- memoryStoreEvictionPolicy="FIFO"/>
- -->
- <!--
- 缓存名为sampleCache3的。
- 这个缓存溢出会到磁盘。磁盘缓存存储在虚拟机重新启动前会持久有效。
- 磁盘的终止线程的时间间隔设置为3分钟,覆盖默认的2分钟。
- <cache name="sampleCache3"
- maxEntriesLocalHeap="500"
- eternal="false"
- overflowToDisk="true"
- diskPersistent="true"
- timeToIdleSeconds="300"
- timeToLiveSeconds="600"
- diskExpiryThreadIntervalSeconds="180"
- memoryStoreEvictionPolicy="LFU">
- </cache>
- -->
- <!--
- Terracotta集群缓存sampleTerracottaCache。
- <cache name="sampleTerracottaCache"
- maxBytesLocalHeap="10m"
- eternal="false"
- timeToIdleSeconds="3600"
- timeToLiveSeconds="1800">
- <terracotta/>
- </cache>
- -->
- </ehcache>
关于配置的属性的含义,可以到官网的文档中查看,这里给出一些常用的属性。
- Cache的以下属性是必须的。
- name:
- cache的唯一标识。
- maxEntriesLocalHeap:
- 在内存创建对象的最大数量。0=无限制。
- 无限制实际指Integer.MAX_SIZE (2147483647)。
- maxEntriesLocalDisk:
- 设置在硬盘上存储的对象的最大数量。默认0,即无限制。
- eternal:
- 设置元素是否持久化。如果是,元素不会过期。
- Cache的以下属性是可选的。
- overflowToOffHeap:
- 此功能仅在企业版的Ehcache。
- 当设置为true,可利用无限制的离堆内存的缓存
- 存储,以提高性能。离堆内存是不受Java
- GC限制的。默认值是false。
- maxBytesLocalHeap:
- 定义多少字节缓存可能会使用虚拟机的堆。如果一个CacheManager的
- maxBytesLocalHeap已经被定义,这个缓存的指定金额将
- 减去从CacheManager的。其他的高速缓存将分享剩下的人。
- 此属性的值是<数字> K | K |米| M| G| G
- 千字节(K| K),兆字节(M| M)或千兆字节(G| G)。
- 例如,maxBytesLocalHeap的“2G”下发2 GB的堆内存。
- 如果您指定一个maxBytesLocalHeap,就不能再使用属性maxEntriesLocalHeap。
- maxBytesLocalOffHeap:
- 此功能仅在企业版的Ehcache。
- 离堆内存量,可以使用这个缓存设置,将保留。
- 此设置将设置overflowToOffHeap为true 。设置explicitly为false来禁用溢出行为。
- 需要注意的是使用时离堆,设置maxEntriesLocalHeap建议至少100个元素,
- 否则性能会出现严重退化,并提出警告。
- 可分配的最低金额为128MB。没有最大值。
- maxBytesLocalDisk:
- As for maxBytesLocalHeap, but specifies the limit of disk storage this cache will ever use.
- timeToIdleSeconds:
- 设置元素闲置时长。单位:秒。(在eternal设置成false的情况下有效)
- 可选属性。值为0意味着元素可以闲置无穷。
- 默认值是0。
- timeToLiveSeconds:
- 设置元素过期时长。单位:秒。(在eternal设置成false的情况下有效)
- 可选属性。值为0意味着,元素可以住无穷。
- 默认值是0。
- diskExpiryThreadIntervalSeconds:
- 磁盘到期线程运行之间的秒数。默认值为120秒。
- diskSpoolBufferSizeMB:
- 这是分配硬盘存储的缓冲区的大小。信息被写入
- 这个区域,然后异步写入到磁盘中。默认大小为30MB。
- 每个缓冲区仅用于由其缓存。如果你遇到内存溢出错误试着
- 降低此值。为了提高硬盘存储性能应考虑增加此值。
- clearOnFlush:
- 调用flush()方法时,硬盘存储缓存被清除。
- 默认值是true。
- memoryStoreEvictionPolicy:
- 内存管理策略,默认是最近最少使用策略(即Least Recently Used,LRU)。
- 其他可选的有先进先出策略(即 First In First Out,FIFO),最少使用频率策略
- (即Less Frequently Used,LFU)。
- copyOnRead:
- 一个元素被复制时是否从缓存中读取。
- 默认false。
- copyOnWrite:
- 一个元素被添加到缓存中时是否被复制。
- 默认false。
EhcacheManagerTest
- package org.base.cache.test;
- import java.net.URL;
- import net.sf.ehcache.Cache;
- import net.sf.ehcache.CacheManager;
- import net.sf.ehcache.Element;
- import net.sf.ehcache.Status;
- /**
- * Ehcache缓存管理的初步学习实例
- * @author blossom
- *
- */
- public class EhcacheManagerTest {
- public static net.sf.ehcache.CacheManager cacheManager = null;
- private static String configPath="org/base/cache/test/myehcache.xml";//配置文件路径,一般会放在源文件夹
- private static String CACHE_MYCACHE1="myCache1";//定义文件中配置的缓存
- //实例化cacheManager,单例模式
- public static CacheManager getCacheManagerInstance(){
- if (cacheManager == null) {
- URL configUrl=null;
- configUrl = EhcacheManagerTest.class.getClassLoader().getResource(configPath);
- cacheManager = CacheManager.create(configUrl);
- }
- return cacheManager;
- }
- public static net.sf.ehcache.CacheManager getCacheManager() {
- return getCacheManagerInstance();//单例缓存管理
- }
- //这个set可以不开放
- public static void setCacheManager(net.sf.ehcache.CacheManager cacheManager) {
- EhcacheManagerTest.cacheManager = cacheManager;
- }
- //添加新缓存
- public static void addCacheByName(String cacheName){
- if(cacheName==null||cacheName.trim().equals("")){
- System.out.println("cacheName is null");
- }else{
- if(getCacheManager().getCache(cacheName.trim())!=null){
- getCacheManager().removeCache(cacheName.trim());
- }
- getCacheManager().addCache(cacheName.trim());
- System.out.println(cacheName+ "重新添加");
- }
- }
- //得到cache对象
- public static Cache getCacheByName(String cacheName){
- Cache cache=null;
- if(cacheName==null||cacheName.trim().equals("")){
- System.out.println("cacheName is null");
- }else{
- if(getCacheManager().getCache(cacheName.trim())!=null){
- cache=getCacheManager().getCache(cacheName.trim());
- }
- }
- return cache;
- }
- //往缓存中添加元素
- public static void putElementToCache(String cacheName,String elementKey,Object elementValue){
- Cache cache=null;
- if(cacheName==null||cacheName.trim().equals("")){
- System.out.println("添加缓存元素失败,cacheName is null");
- }else if(elementKey==null||elementValue==null){
- System.out.println("添加缓存元素失败,elementKey or elementValue is null");
- }else{
- if(getCacheByName(cacheName.trim())!=null){//缓存存在
- cache=getCacheByName(cacheName.trim());
- }else{//缓存不存在
- addCacheByName(cacheName.trim());
- cache=getCacheByName(cacheName.trim());
- }
- //对cache对象添加Element
- Element element=null;
- if(cache.get(elementKey.trim())!=null){
- cache.remove(elementKey.trim());
- }
- element=new Element(elementKey.trim(),elementValue);
- cache.put(element);
- System.out.println("添加缓存元素:"+elementKey+"成功!");
- }
- }
- //从缓存中获取指定key的值
- public static Object getElementValueFromCache(String cacheName,String elementKey){
- Object result=null;
- Cache cache=null;
- if(cacheName==null||cacheName.trim().equals("")){
- System.out.println("获取缓存元素失败,cacheName is null");
- }else if(elementKey==null){
- System.out.println("获取缓存元素失败,elementKey is null");
- }else{
- if(getCacheByName(cacheName.trim())!=null){//缓存存在
- cache=getCacheByName(cacheName.trim());
- Element element=null;
- if(cache.get(elementKey.trim())!=null){
- element=cache.get(elementKey.trim());
- if(element.getObjectValue()==null){
- System.out.println("缓存中"+elementKey+" 的值为空.");
- }else{
- result=element.getObjectValue();
- }
- }else{
- System.out.println("缓存中"+elementKey+" 的Element值为空.");
- }
- }else{//缓存不存在
- System.out.println("获取缓存元素失败,缓存"+cacheName+" 为空.");
- }
- }
- return result;
- }
- /**
- * 把所有cache中的内容删除,但是cache对象还是保留.
- * Clears the contents of all caches in the CacheManager,
- * but without removing any caches.
- */
- public static void clearAllFromCacheManager(){
- if(getCacheManager()!=null){
- getCacheManager().clearAll();
- System.out.println("CacheManager was clearAll...");
- }
- }
- /**
- * 把所有cache对象都删除。慎用!
- * Removes all caches using removeCache(String) for each cache.
- */
- public static void removalAllFromCacheManager(){
- if(getCacheManager()!=null){
- getCacheManager().removalAll();
- System.out.println("CacheManager was removalAll...");
- }
- }
- //不用缓存时,要关闭,不然会占用cpu和内存资源。
- public static void shutdownCacheManager(){
- if(getCacheManager()!=null){
- getCacheManager().shutdown();
- System.out.println("CacheManager was shutdown...");
- }
- }
- //打印方法1,为了测试用
- public static void printCache(Cache cache){
- System.out.println("缓存状态: "+cache.getStatus().toString());
- if(cache==null){
- System.out.println("cache is null,no print info.");
- }else if(cache.getStatus().toString().equals(Status.STATUS_UNINITIALISED)){
- System.out.println("缓存状态: 未初始化"+cache.getStatus().toString());
- }else if(cache.getStatus().toString().equals(Status.STATUS_SHUTDOWN)){
- System.out.println("缓存状态: 已关闭"+cache.getStatus().toString());
- }else if(cache.getStatus().toString().equals(Status.STATUS_ALIVE)){
- if(cache.getKeys().size()==0){
- System.out.println(cache.getName()+" exits,but no value.");
- }else{
- for(int i=0;i<cache.getKeys().size();i++){
- Object thekey=cache.getKeys().get(i);
- Object thevalue=cache.get(thekey);
- System.out.println(cache.getName()+"--"+i+",key:"+thekey.toString()+",value:"+thevalue.toString());
- }
- }
- }
- }
- //打印方法2,为了测试用
- public static void printCacheByName(String cacheName){
- if(cacheName==null||cacheName.trim().equals("")){
- System.out.println("cacheName is null,no print info.");
- }else{
- if(getCacheManager().getCache(cacheName.trim())!=null){
- Cache cache=getCacheManager().getCache(cacheName.trim());
- printCache(cache);
- }else{
- System.out.println(cacheName+" --null");
- }
- }
- }
- public static void main(String[] sdfsf){
- Cache cache1=EhcacheManagerTest.getCacheByName(EhcacheManagerTest.CACHE_MYCACHE1);
- printCache(cache1);
- EhcacheManagerTest.putElementToCache(EhcacheManagerTest.CACHE_MYCACHE1, "111", "111haah");
- EhcacheManagerTest.putElementToCache(EhcacheManagerTest.CACHE_MYCACHE1, "222", "222haah");
- EhcacheManagerTest.putElementToCache(EhcacheManagerTest.CACHE_MYCACHE1, "333", "333haah");
- printCache(cache1);
- EhcacheManagerTest.putElementToCache(EhcacheManagerTest.CACHE_MYCACHE1, "111", "111的新值。");
- System.out.println(EhcacheManagerTest.getElementValueFromCache(EhcacheManagerTest.CACHE_MYCACHE1, "111"));
- printCache(cache1);
- clearAllFromCacheManager();
- printCache(cache1);
- removalAllFromCacheManager();
- printCache(cache1);
- shutdownCacheManager();
- }
- /*打印
- 缓存状态: STATUS_ALIVE
- 添加缓存元素:111成功!
- 添加缓存元素:222成功!
- 添加缓存元素:333成功!
- 缓存状态: STATUS_ALIVE
- 添加缓存元素:111成功!
- 111的新值。
- 缓存状态: STATUS_ALIVE
- CacheManager was clearAll...
- 缓存状态: STATUS_ALIVE
- CacheManager was removalAll...
- 缓存状态: STATUS_SHUTDOWN
- CacheManager was shutdown...
- */
- }
通过上面的使用,我们初步了解Ehcache的api。在web环境下,我们可以注入EhcacheManager对象,
把需要的数据,放入缓存。在其他地方取数据的时候,就从过EhcacheManager来获取,而不是直接
从数据库查询。这样就提高了效率。
值得注意的是,缓存的使用一般在一些数据比较固定的地方。如果某个查询需要保证数据的实时性,使用缓存
就是错误的做法。
EhCache缓存学习相关推荐
- Spring Boot 2.x基础教程:使用EhCache缓存集群
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 上一篇我们介绍了在Spring Boot中整合EhCac ...
- SpringBoot集成Cache缓存(Ehcache缓存框架,注解方式)
1.说明 Spring定义了CacheManager和Cache接口, 用来统一不同的缓存技术, 例如JCache,EhCache,Hazelcast,Guava,Redis等. 本文通过Spring ...
- mybatis配置ehcache缓存
1:在spring配置文件中加载缓存配置文件 <!-- 使用ehcache缓存 --> <bean id="ehCacheManager" class=" ...
- Ehcache 缓存监控配置
监控 ehcache缓存: 1,下载: http://terracotta.org/downloads/open-source/destination?name=ehcache-monitor-kit ...
- Ehcache 缓存
1 package org.jeecgframework.core.util; 2 3 import net.sf.ehcache.Cache; 4 import net.sf.ehcache.Cac ...
- shiro教程:整合ehcache缓存
这个是在ssm的基础上再去整合shiro和ehcache的,整合ehcache主要是为了减少后台shiro拦截的次数,因为如果我们不使用缓存的话,后台shiro的认证和授权的拦截器就会反复的进行拦截, ...
- javaweb项目搭建ehcache缓存系统
转载自 javaweb项目搭建ehcache缓存系统 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider,同时在项目开发中 ...
- [原创]mybatis中整合ehcache缓存框架的使用
mybatis整合ehcache缓存框架的使用 mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓 ...
- 一文玩转 EhCache 缓存框架!
Ehcache 介绍 EhCache 从 Hibernate 发展而来,是一个纯Java的进程内缓存框架,具有快速.精干等特点.Ehcache是一种广泛使用的开源Java分布式缓存.主要面向通用缓存, ...
最新文章
- isolate-user-vlan隔离用户vlan的配置
- python之内置函数(二)与匿名函数、递归函数初识
- 学python可以做什么产品-学习Python到底有什么用?
- pygtk在windows的安装
- linux跳转乌班图服务器,Ubuntu18.04连接Linux服务器与文件传输
- 【Eclipse使用教程】Java导包快捷键
- 卡内基梅隆大学计算机专业有哪些,卡内基梅隆大学计算机系统类大学排名最新资讯总结篇...
- 人员-组织 结构 数据库关系设计
- CTS、CLS和CLR
- 自动化测试 (二) 连连看外挂
- HR_NZ_ROUNDING_DECIMALS DUMP
- R语言分析股票指数的GARCH效应
- 高级架构师_Elasticsearch_第二章kibana+IK分词器安装+索引操作+ 映射操作
- java获取ip地址与网络接口
- 电脑开机时网络连接一直转圈,出现红叉
- Android手机蓝牙连接笔记本电脑蓝牙
- BMW Standard Tools 宝马FSC工具套装下载
- 阿里云服务器ECS开放8080端口
- 数据结构之顺序表的删除、查找、遍历
- sql语句的批量添加
热门文章
- linux rc.local权限,Linux开机启动rc.local不执行分析
- OpenShift 4 之Istio-Tutorial (6) 服务恢复能力(重试、超时、断路器)
- 初步创建vue/cli工程教程
- 金蝶kis仓库管理系统演示_金蝶KIS专业版生产管理的系统亮点功能
- linux裸设备大小,SUSE Linux 十 配置裸设备(raw devices)
- java 内存指针_java内存模型详解
- 高级会计可以用计算机,高会无纸化考试计算器不好用 建excel计算可以吗?官方回复!...
- java中的四个跳转语句_Java中的流程控制语句 (基础篇四)
- python计算两字符串中的位置_从Python中的字符串中获取两个字符
- html5播放视频自动循环播放,HTML5 通过Vedio标签实现视频循环播放的示例代码