SpringMVC(7) EhCache实现缓存数据

       EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。ehcache直接在jvm虚拟机中缓存,速度快,效率高;但是缓存共享麻烦,集群分布式应用不方便。


EhCache缓存数据实现步骤:

①导入jar包       (点击下载EhCache文档及jar包资源  密码:53vo)

②引入xml配置文件

ehcache.xml:

maxElementsInMemory:缓存中允许创建的最大对象数
eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是 0 就意味着元素可以停顿无穷长的时间。
timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
overflowToDisk:内存不足时,是否启用磁盘缓存。
memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。LRU和FIFO算法这里就不做介绍。LFU算法直接淘汰使用比较少的对象,在内存保留的都是一些经常访问的对象。对于大部分网站项目,该算法比较适用。

如果应用需要配置多个不同命名并采用不同参数的Cache,可以相应修改配置文件,增加需要的Cache配置即可。
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="config/ehcache.xsd">
	<!-- 磁盘存储的路径 -->
	<diskStore path="C:/ehcache" />
	
        <!-- 一个缓存 -->
	<cache 
		name="articleCache"
		maxElementsInMemory="1"
		eternal="true"
		timeToIdleSeconds="0" 
		timeToLiveSeconds="0" 
		overflowToDisk="true"
		maxElementsOnDisk="1000000" 
		diskPersistent="false"
		diskExpiryThreadIntervalSeconds="120" 
		memoryStoreEvictionPolicy="LRU" />
	
</ehcache>

③缓存操作 :    

        CacheManager cm = CacheManager.create();//创建CacheManager缓存管理对象
        Cache cache = cm.getCache("demoCache");// 通过cm可以生成指定名称的Cache对象
        cm.removeCache("demoCache");//移除指定名称的Cache对象
        //有了Cache对象之后就可以开始操作Cache对象了
        Element element = new Element("key", "value");//往Cache对象中添加元素
        cache.put(element);// 将数据存储到cache中
        cache.get("key");//从cache中取回元素
        cache.remove("key");//从Cache中移除一个元素

 //==============注意:对于缓存的对象都是必须可序列化的。==============

ex:我的bean类:  public class Articles implements Serializable {  ...  }

这里拿个我目前阶段正在做的项目来举实例吧:

spring配置文件中创建CacheManager缓存管理对象

<bean class="net.sf.ehcache.CacheManager" factory-method="create"></bean>

抽取EhcacheUtil工具类:

/**
 *  实现缓存数据的存取
 */
public class EhcacheUtil {

	/**
	 * 从缓存中获取数据
	 * @param cm:缓存管理对象
	 * @param cachename:ehcache.xml配置文件中的name值
	 * @param key:在缓存中储存的数据对应存放值
	 * @return
	 */
	public static Element getElement(CacheManager cm,String cachename,String key){
		Cache cache = cm.getCache(cachename);//通过cm可以生成指定名称(cachename)的Cache对象
		//对于以后查询的种类会更多因此这个参数需要采用传值  ex:articleCache,userCache,imageCache
		Element element = cache.get(key);//从cache(key)中取回元素
		return element;
	}

	/**
	 * 存储数据到缓存中
	 * @param cm:缓存管理对象
	 * @param cachename:ehcache.xml配置文件中的name值
	 * @param key:在缓存中储存的数据对应存放值
	 * @param value:在缓存中储存的数据
	 */
	public static void setElement(CacheManager cm,String cachename,String key,Object value){
		Cache cache = cm.getCache(cachename);
		Element element = new Element(key, value);
		cache.put(element);//往cache(key)中添加元素
	}

}

service中实现缓存:  这里看看方法queryCache中是怎么缓存数据,以及获取缓存中的数据即可,具体的还要根据自己的项目要求来~~

/**
 *  文章业务逻辑处理:
 *  增删改查 + 实现缓存
 */
@Service
public class ArticlesServiceImpl implements IArticlesService {

    @Autowired
    private ArticlesDaoImpl dao;

    @Autowired
    private CacheManager cm;//@Autowired注入spring配置文件中创建CacheManager

    private Boolean iscache=false;   //iscache标识-->缓存中区分增删改   true:表示缓存已经改变,就会刷新之后查询内容,false:在缓存中查找内容

    @Override
    public void addArticle(Articles article, ServletContext context) throws Exception {
        String newName = createHtml(article, context);
        article.setHtmlurl("/temp/"+newName);//设置htmlurl的值
        dao.addArticle(article);
        iscache=true;
    }

    @Override
    public PageList<Articles> queryAll(Boolean flag, Conditions condition) throws Exception {
//        return dao.queryAll(flag,condition);
        PageList<Articles> pageList = queryCache(flag, condition,iscache);
        iscache=false;
        return pageList;
    }

    //缓存中   当数据增删改的时候-->执行重新查询  否则就从缓存中查询内容  -->因此要注意一些逻辑 不要导致在缓存中查询不符合的内容
    private PageList<Articles> queryCache(Boolean flag, Conditions condition, Boolean iscache) throws Exception {
        //解决分页问题
        /**
         * 缓存中是存储了多个element,element依据key来获取
         * 前台存储:beforelist1  -->末尾的数字1表示分页查询时的页数
         * 后台存储:afterlist1
         */
        String key="";
        if (flag) {    //后台
            key="afterlist"+condition.getCurrentPage();
        }else{    //前台
            key="beforelist"+condition.getCurrentPage();
        }
        System.out.println("前台before,后台after --> "+key);
        Element element = EhcacheUtil.getElement(cm, "articleCache", key);//这里的key的作用是不同的缓存   get:从key缓存中取数据
        PageList<Articles> pageList = null;

        if (element == null||iscache) {
            /**
             *  只要更新数据,以前的所有缓存先清空     注意:这里应该还要判断文章类型type+title选择的变化  如果变化  也应该清空缓存 !!
             */
            if(iscache){
//                cm.removeCache("articleCache"); //只有增加、删除、修改,才需要移除缓存
                cm.getCache("articleCache").removeAll();//移除articleCache中数据  这行代码很重要,   用上一行的代码会出错-->空指针
            }
            pageList = dao.queryAll(flag, condition);
            EhcacheUtil.setElement(cm, "articleCache", key, pageList);
        } else {
            pageList = (PageList<Articles>) element.getObjectValue();
        }
        return pageList;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郑清

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值