27. Spring Boot 缓存注解详解: @Cacheable、@CachePut、 @CacheEvict、@Caching、@CacheConfig

时间:2022-06-06 20:43:12

27. Spring Boot 缓存注解详解:  @Cacheable、@CachePut、 @CacheEvict、@Caching、@CacheConfig

 1、使用OGNL的命名规则来定义Key的值

@Cacheable(cacheNames = {"user"},key = "#root.methodName + '[' + #id + ']'")
@Override
public User selectByPrimaryKey(Integer id) {
return userMapper.selectByPrimaryKey(id);
}

27. Spring Boot 缓存注解详解:  @Cacheable、@CachePut、 @CacheEvict、@Caching、@CacheConfig

2、自定义Key生成器

@Configuration
public class MyConfig { @Bean
public KeyGenerator myKeyGenerator(){
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... params) {
String key = o.getClass().getSimpleName()+"."+method.getName()+Arrays.asList(params);
return key;
}
};
} }

key 属性和keyGenerator属性只能二选一

@Cacheable(cacheNames = {"user"},keyGenerator = "myKeyGenerator")
@Override
public User selectByPrimaryKey(Integer id) {
return userMapper.selectByPrimaryKey(id);
}

3、加条件过滤

/**condition成立的条件缓存,unless成立的条件不缓存。以下实例含义为:id > 1 且 id != 2 的缓存
*
* 1、condition:id >1的会被缓存,只执行一次查询SQL,id <= 1的每次查询都会执行SQL,#a0是取第一个参数,也可以用“#参数名” 即:#id
* 2、unless: id==2的不缓存
* 3、sync: 异步方式缓存
* sync 和 unless 不能同时支持,否则会报错
*/
@Cacheable(cacheNames = {"user"},keyGenerator = "myKeyGenerator",condition = "#a0>1", unless="#id==2", sync=true)
@Override
public User selectByPrimaryKey(Integer id) {
return userMapper.selectByPrimaryKey(id);
}

4、缓存更新  @CachePut

/**
* @CachePut:既调用方法,又更新缓存数据;同步更新缓存
* 修改了数据库的某个数据,同时更新缓存;
* 运行时机:
* 1、先调用目标方法
* 2、将目标方法的结果缓存起来
*
* 测试步骤:
* 1、查询1号员工;查到的结果会放在缓存中;
* key:1 value:name:张三
* 2、以后查询还是之前的结果
* 3、更新1号员工;【name:zhangsan;age:10】
* 将方法的返回值也放进缓存了;
* key:传入的employee对象 值:返回的employee对象;
* 4、查询1号员工?
* 应该是更新后的员工;
* key = "#record.id":使用传入的参数的员工id;
* key = "#result.id":使用返回后的id
* @Cacheable的key是不能用#result
* 为什么是没更新前的?【1号员工没有在缓存中更新】
*
*/
@CachePut(cacheNames = {"user"},key = "#record.id")
@Override
public User updateByPrimaryKeySelective(User record) {
userMapper.updateByPrimaryKeySelective(record);
return userMapper.selectByPrimaryKey(record.getId());
}
4、缓存清除@CacheEvict
/**
* @CacheEvict:缓存清除
* key:指定要清除的数据
* allEntries = true:指定清除这个缓存中所有的数据
* beforeInvocation = false:缓存的清除是否在方法之前执行
* 默认代表缓存清除操作是在方法执行之后执行;如果出现异常缓存就不会清除
*
* beforeInvocation = true:
* 代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除
*
*
*/
@CacheEvict(value="emp",beforeInvocation = true/*key = "#id",*/)
@Override
public int deleteByPrimaryKey(Integer id) {
System.out.println("delete user : " + id);
return id;
//return userMapper.deleteByPrimaryKey(id);
}

5、复杂的

/**
* 复杂的缓存规则:
* 1.以name查询还会去查询数据库:因为有@CachePut注解,所以这方法一定要执行的,@CachePut把方法执行的结果缓存到缓存
* 2. (1), (1) : 每次都会执行SQL,因为有@CachePut
* (1),(2): (1)执行SQL,不执行
*
*
* */
@Caching(
cacheable = {
@Cacheable(cacheNames = {"user"},key="#name") //(1)根据name查询user
},
put = {
@CachePut(cacheNames = {"user"},key="#result.id") //(2) 根据id查询user 以另一种key将查询出的结果缓存到缓存中
}
)
@Override
public User selectByName(String name) {
return userMapper.selectByName(name);
}

6. 全局参数提取 @CacheConfig

@Service
@CacheConfig(cacheNames={"user"},keyGenerator = "myKeyGenerator")
public class UserServiceImpl implements UserService { @Autowired
UserMapper userMapper; @CacheEvict(/*value="emp",*/ beforeInvocation = true/*key = "#id",*/)
@Override
public int deleteByPrimaryKey(Integer id) {
System.out.println("delete user : " + id);
return id;
//return userMapper.deleteByPrimaryKey(id);
}
}