博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring整合ehcache 注解实现查询缓存,并实现实时缓存更新或删除
阅读量:5334 次
发布时间:2019-06-15

本文共 8002 字,大约阅读时间需要 26 分钟。

写在前面:上一篇博客写了spring cache和ehcache的基本介绍,个人建议先把这些最基本的知识了解了才能对今天主题有所感触。不多说了,开干!

注:引入jar

net.sf.ehcache
ehcache
2.8.3

 

第一步:首先配置ehcache.xml

第二步:在spring.xml的配置文件中引入schema, 

      xmlns:aop="http://www.springframework.org/schema/aop"和http://www.springframework.org/schema/cache  http://www.springframework.org/schema/cache/spring-cache-3.2.xsd

      缓存的配置:

OK!缓存的相关配置已经完成。下面开始编写测试程序。这里需要连接数据库,我就不写了。这里为了方便就随便找了之前写过的model,这个model就是AOP注解实现日志管理的实体,为了偷懒就直接用了,希望你们不要误解,没有特殊意义的

第三步:编写model,这里需要注意,要实现缓存的实体必须要序列化 private static final long serialVersionUID = -6579533328390250520L;  关于序列化的生成这里就不介绍了,大家可以百度看看。

package org.shop.entity;import java.io.Serializable;import java.util.Date;public class SystemLog implements Serializable {     private static final long serialVersionUID = -6579533328390250520L;    private String id;    private String description;    private String method;    private Long logType;    private String requestIp;    private String exceptioncode;    private String exceptionDetail;    private String params;    private String createBy;    private Date createDate;    public String getId() {        return id;    }    public void setId(String id) {        this.id = id == null ? null : id.trim();    }    public String getDescription() {        return description;    }    public void setDescription(String description) {        this.description = description == null ? null : description.trim();    }    public String getMethod() {        return method;    }    public void setMethod(String method) {        this.method = method == null ? null : method.trim();    }    public Long getLogType() {        return logType;    }    public void setLogType(Long logType) {        this.logType = logType;    }    public String getRequestIp() {        return requestIp;    }    public void setRequestIp(String requestIp) {        this.requestIp = requestIp == null ? null : requestIp.trim();    }    public String getExceptioncode() {        return exceptioncode;    }    public void setExceptioncode(String exceptioncode) {        this.exceptioncode = exceptioncode == null ? null : exceptioncode.trim();    }    public String getExceptionDetail() {        return exceptionDetail;    }    public void setExceptionDetail(String exceptionDetail) {        this.exceptionDetail = exceptionDetail == null ? null : exceptionDetail.trim();    }    public String getParams() {        return params;    }    public void setParams(String params) {        this.params = params == null ? null : params.trim();    }    public String getCreateBy() {        return createBy;    }    public void setCreateBy(String createBy) {        this.createBy = createBy == null ? null : createBy.trim();    }    public Date getCreateDate() {        return createDate;    }    public void setCreateDate(Date createDate) {        this.createDate = createDate;    }}
View Code

第四步:编写dao,service

package org.shop.dao;import org.shop.entity.SystemLog;public interface SystemLogMapper {    int deleteByPrimaryKey(String id);    int insert(SystemLog record);    int insertSelective(SystemLog record);    SystemLog selectByPrimaryKey(String id);    int updateByPrimaryKeySelective(SystemLog record);    int updateByPrimaryKey(SystemLog record);        int count();}
View Code
public interface SystemLogService {    int deleteSystemLog(String id);    int insert(SystemLog record);        int insertTest(SystemLog record);    SystemLog findSystemLog(String id);        int updateSystemLog(SystemLog record);        int count();}
View Code

第五步:编写serviceImpl并添加缓存注解这里缓存注解的参数不介绍了,不懂得看我上一篇博客,我这里先把需要的注解都写上了,一会一个一个介绍。

@Service("systemLogService")public class SystemLogServiceImpl implements SystemLogService {    @Resource    private SystemLogMapper systemLogMapper;        @Override    public int deleteSystemLog(String id) {                      return systemLogMapper.deleteByPrimaryKey(id);    }     @Override    //@CachePut(value="myCache")    //@CacheEvict(value="myCache",allEntries=true,beforeInvocation=true)    @CacheEvict(value="myCache",key="0",beforeInvocation=true)    public int insert(SystemLog record) {                      return systemLogMapper.insertSelective(record);    }     @Override    @Cacheable(value="myCache",key="#id")    public SystemLog findSystemLog(String id) {                     return systemLogMapper.selectByPrimaryKey(id);    }     @Override    public int updateSystemLog(SystemLog record) {                     return systemLogMapper.updateByPrimaryKeySelective(record);    }    @Override    public int insertTest(SystemLog record) {                   return systemLogMapper.insert(record);    }     @Override    @Cacheable(value="myCache",key="0")    public int count() {           int num = systemLogMapper.count();           return num;    }}

第六步:编写controller,即我们的测试。

@Controller@RequestMapping("systemLogController")public class SystemLogController {    @Resource    private SystemLogService systemLogService;        @RequestMapping("testLog")    public ModelAndView testLog(){            ModelMap modelMap = new ModelMap();        SystemLog systemLog = systemLogService.findSystemLog("c30e2398-079a-406b-a2f7-a85fa15ccac7");        modelMap.addAttribute("data", systemLog);        return new ModelAndView("index",modelMap);    }    @RequestMapping("insert")    @ResponseBody    public boolean Insert(SystemLog record){        systemLogService.insert(record);        return true;    }        @RequestMapping("test1")    public ModelAndView test1(){        ModelMap modelMap = new ModelMap();        int num =systemLogService.count();        modelMap.addAttribute("num", num);        return  new ModelAndView("pageEhcache",modelMap);    }    }

我们先测试查询的缓存,即serviceImpl中的 findSystemLog(String id) 方法,我们访问testLog.do,第一次运行如下图,注意控制台中的heap和 disk

再一次访问testLog.do,运行你会发现没有访问数据库,如图:

到此查询的缓存我们实现了,但是关于缓存的处理我们并没有做完,我们应该在深入思考下,在上面查询的缓存生命周期内,我们对刚才查询的表进行了增删改操作,这时我们再访问该查询方法,你会发现我们的数据并没有改变,还是增删改操作之前的数据(因为缓存的生命还在),这里是不是问题呢?此时我们需要对查询的缓存进行更新或删除。

下面我们看serviceImpl中的insert方法和count()方法,count的方法是统计表中的数据总记录,insert方法是对该表进行新增一条记录,insert的缓存注解用的是@CacheEvict(value="myCache",key="0",beforeInvocation=true),这里清除的是指定缓存,也就是count方法中@Cacheable(value="myCache",key="0")的,(serviceImpl中注释的@CacheEvict(value="myCache",allEntries=true,beforeInvocation=true)是清除所有的缓存,这里我就不演示了,道理是一样的)

这里我提供一个测试pageEhcache.jsp页面,

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>      测试                  

<%=new Date()%>

这是一个练习

id:
总数:

${num}

 我们先访问test1.do,看下表中的记录数并注意控制台变化

页面显示如下,注意总数是67

再一次访问test1.do,没有访问数据库,说明count()方法的缓存生效了,

接下来开始新增记录,点击插入按钮

注意控制台显示,这里执行了inserSQL语句,并remove了count()方法上的缓存,

接下来再次访问test1.do,我们看到总数变化了,增加了一条,说明我们把之前count()方法上的缓存删除了,又执行了查询总数的sql

再次访问test1.do,count()方法的缓存生效了,对吧!这个就是@CacheEvict注解的作用。

在insert()方法上还有@CachePut(value="myCache")注解,上面的serviceImpl中注释了,它的作用是:@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

我这里就不做演示了,你们可以自己动手试试。

总结我个人的理解,对查询方法增加缓存容易,但对于缓存的更新的处理就比较麻烦,我上面的serviceImpl中写了三种处理方式,

       1.用@CachePut处理,这中方法需要对指定缓存key保持一致,尽管这样,还是不行,因为它返回的缓存是int(增加或删除或修改的记录数或是该记录的对象,这对我们查询所有或部分记录的缓存还是不可行的)

       2.用@CacheEvict(value="myCache",key="0",beforeInvocation=true)处理,清除我们指定key的缓存,这种方式缺点是麻烦,需要我们注意每一个缓存的key

       3.@CacheEvict(value="myCache",allEntries=true,beforeInvocation=true)处理,清除所有缓存,这种方式最省事,但会把其他缓存也一同清除。

随着业务的复杂性的不断增加,这些处理方式,可能会增加代码的复杂性,然后我想到的是对DB层进行缓存,可以利用redis,mamchched的进行处理。当然对于一般的web应用运用ehcache已经刻一解决了,但是对大数据量的运用db级别的缓存效果性能可能会更好。

以上纯粹是个人想法。另外我也想了想缓存到底在哪些场景下应用会比较好,不知道你们是怎么认为的。也请大家给点建议。

转载于:https://www.cnblogs.com/jianjianyang/p/4938765.html

你可能感兴趣的文章
MATLAB作图方法与技巧(一)
查看>>
上海淮海中路上苹果旗舰店门口欲砸一台IMAC电脑维权
查看>>
Google透露Android Market恶意程序扫描服务
查看>>
给mysql数据库字段值拼接前缀或后缀。 concat()函数
查看>>
迷宫问题
查看>>
【FZSZ2017暑假提高组Day9】猜数游戏(number)
查看>>
泛型子类_属性类型_重写方法类型
查看>>
eclipse-将同一个文件分屏显示
查看>>
对闭包的理解
查看>>
练习10-1 使用递归函数计算1到n之和(10 分
查看>>
Oracle MySQL yaSSL 不明细节缓冲区溢出漏洞2
查看>>
windows编程ASCII问题
查看>>
.net webService代理类
查看>>
Code Snippet
查看>>
Node.js Express项目搭建
查看>>
zoj 1232 Adventure of Super Mario
查看>>
1201 网页基础--JavaScript(DOM)
查看>>
组合数学 UVa 11538 Chess Queen
查看>>
oracle job
查看>>
Redis常用命令
查看>>