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);
}

 

 

 

 

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);
    }
}

 

posted @ 2018-12-13 10:09  超轶绝尘  阅读(5370)  评论(0编辑  收藏  举报