springboot使用缓存(二)

一、概述

有人看了上篇springboot使用缓存(一),觉得很有用,但应该又有人发现,这种方式虽然简单,还存在一些缺陷。

的确如此!

像上篇博文把缓存过期时间设为600秒,那如果底层数据库的数据已经更新或删除了,前端还从缓存里取数,势必会返回错误的数据

为了解决这个问题,其实还有一些更细致的配置。

二、关于缓存的注解

除了上篇博文中用到的@Cacheable外,springboot还提供了其他注解

就我个人的理解:

@Cacheable相当于使用缓存,适用于数据库的查询方法

@CachePut相当于更新缓存,适用于数据库的插入或更新方法

@CacheEvit相当于删除缓存,适用于数据库的删除方法

注 解 描 述
@Cacheable 表明Spring在调用方法之前, 首先应该在缓存中查找方法的返回值。 如果这个值能够找到, 就会 返回缓存的值。 否则的话, 这个方法就会被调用, 返回值会放到缓存之中
@CachePut 表明Spring应该将方法的返回值放到缓存中。 在方法的调用前并不会检查缓存, 方法始终都会被 调用
@CacheEvict 表明Spring应该在缓存中清除一个或多个条目
@Caching 这是一个分组的注解, 能够同时应用多个其他的缓存注解

@Cacheable和@CachePut有一些共有的属性

属 性 类 型 描 述
value String[] 要使用的缓存名称
condition String SpEL表达式, 如果得到的值是false的话, 不会将缓存应用到方法调用上
key String SpEL表达式, 用来计算自定义的缓存key
unless String SpEL表达式, 如果得到的值是true的话, 返回值不会放到缓存之中

三、自定义缓存的key

有时候我们需要自定义缓存的key,Spring暴露了一些很有用的元数据 

表 达 式 描 述
#root.args 传递给缓存方法的参数, 形式为数组
#root.caches 该方法执行时所对应的缓存, 形式为数组
#root.target 目标对象
#root.targetClass 目标对象的类, 是#root.target.class的简写形式
#root.method 缓存方法
#root.methodName 缓存方法的名字, 是#root.method.name的简写形式
#result 方法调用的返回值(不能用在@Cacheable注解上)
#Argument 任意的方法参数名(如#argName) 或参数索引(如#a0或#p0)

四、案例

@Cacheable(cacheNames = "emp")
    public Employee getEmp(Integer id) {
        System.out.println("查询" + id + "号员工");
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }

 @CachePut(cacheNames = "emp", key = "#employee.id")
    public Employee updateEmp(Employee employee) {
        System.out.println("updateEmp:" + employee);
        employeeMapper.updateEmp(employee);
        return employee;
    }

  @CacheEvict(cacheNames = "emp", key = "#id")
    public void deleteEmp(Integer id) {
        employeeMapper.deleteEmpById(id);
    }

参考:

https://www.cnblogs.com/mzq123/p/12629142.html

原文地址:https://www.cnblogs.com/wangbin2188/p/15011665.html