1. @Cacheable
Cacheable 注解不带参数时,是以方法参数值的组合作为key值,那么此时就会出现问题,即当两个方法的参数类型、个数都是一样时,如果两个方法在调用时传入的参数值也一样,那么就会出现数据读取错误的情况,所以指定缓存的key非常重要。
key如何指定呢?:
参考链接:https://blog.youkuaiyun.com/BinshaoNo_1/article/details/84579326
key指定用的是Spring EL表达式,这里的EL表达式可以使用方法参数及参数是对象时,它们对应的成员变量。
使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。
@Cacheable(value="users", key="#id")
public User find(Integer id) {
return null;
}
@Cacheable(value="users", key="#p0")
public User find(Integer id) {
return null;
}
@Cacheable(value="users", key="#user.id")
public User find(User user) {
return null;
}
@Cacheable(value="users", key="#p0.id")
public User find(User user) {
return null;
}
除了上述使用方法参数作为key之外,Spring还为我们提供了一个root对象可以用来生成key。通过该root对象我们可以获取到以下信息。
当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。如:
@Cacheable(value={"users", "xxx"}, key="caches[1].name")
public User find(User user) {
return null;
}
如果要调用当前类里面的方法:
@Cacheable(value={"TeacherAnalysis_public_chart"}, key="#root.target.getDictTableName() + '_' + #root.target.getFieldName()")
public List<Map<String, Object>> getChartList(Map<String, Object> paramMap) {
}
public String getDictTableName(){
return "";
}
public String getFieldName(){
return "";
}
如果觉得每次都要设置key比较麻烦的话,可以直接在redis的配置类里面自定义缓存key生成策略,比如见下:
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator(){
@Override
public Object generate(Object target, java.lang.reflect.Method method, Object... params) {
StringBuffer sb = new StringBuffer();
sb.append(target.getClass().getName());
sb.append(method.getName());
for(Object obj:params){
sb.append(obj.toString());
}
return sb.toString();
}
};
}
除了 key 属性外,还有condition属性指定缓存发生的条件
condition 属性默认为空,表示将缓存所有的调用情形。
其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。
如下示例表示只有当user的id为偶数时才会进行缓存:
@Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")
public User find(User user) {
System.out.println("find user by user " + user);
return user;
}
2. @CachePut
@CachePut标注的方法无论如何都是执行操作,再将执行结果以键值对的形式存入指定的缓存中。
一般用于更新,需要注意的是,该注解里面的key属性要和查找方法里面cacheable注解的key属性内容一致,才可以更新进对应的缓存区内容。
3. @CacheEvict
通常用在删除方法上,用来从缓存中移除相应数据。
除了同@Cacheable一样的参数之外,它还有下面两个参数:
①allEntries:非必需,默认为false。当为true时,会移除所有数据
②beforeInvocation:非必需,默认为false,会在调用方法之后移除数据。当为true时,会在调用方法之前移除数据。