二. Spring Cache 的概念
二.一 几个重要概念&缓存注解
二.二 @Cacheable/@CachePut/@CacheEvict 主要的参数
二.三 SpEL上下文数据
Spring Cache提供了一些供我们使用的SpEL上下文数据,下表直接摘自Spring官方文档:
注意:
1.当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。 如
@Cacheable(key = "targetClass + methodName +#p0")
2.使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。 如:
@Cacheable(value="users", key="#id") @Cacheable(value="users", key="#p0")
SpEL提供了多种运算符
三. SpringCache 的注解用法
通常情况下, 传入的参数为 key, 返回的结果为 value
三.一 @Cacheable
@Override // 指定了参数为 id: 变成了: value::id 的key值 @Cacheable(value=KEY_PRE,key = "#id") public User findById(int id) { return userMapper.findById(id); }
进行测试 传入的参数 是 40
当参数有多个时
@Cacheable(value = KEY_PRE) @Override public List<User> findByNameAndSex(String name, String sex) { return userMapper.findByNameAndSex(name,sex); }
不指定 key 时 (传入参数 name为 周小欢 sex为 女 时), 默认的生成的缓存 key为:
user_::top.yueshushu.learn.service.UserServiceImpl.findByNameAndSex.周小欢女
可以 通过 key 进行指定
@Cacheable(value = KEY_PRE,key = "#name") @Override public List<User> findByNameAndSex(String name, String sex) { return userMapper.findByNameAndSex(name,sex); }
生成 后的 key 为: user_::周小欢
key值 可以进行拼接
@Cacheable(value = KEY_PRE,key = "#name+#sex")
生成后的key 为: user_::周小欢女
也可以使用 #p+参数序号 来指定
@Cacheable(value = KEY_PRE,key = "#p0+#p1")
生成的key 是: user_::周小欢女
也可以使用 SpEL 上下文进行处理
@Override @Cacheable(value = KEY_PRE,key="#root.targetClass+#root.methodName+#id") public User findById(int id) { return userMapper.findById(id); }
传入参数是 40 的话,
生成的 key 是: user_::class top.yueshushu.learn.service.UserServiceImplfindById40
也可以指定 条件 condition 当条件满足时,才使用缓存。
传入 id 为 40, <30为false, 即条件为 false
@Cacheable(value = KEY_PRE,key="#root.targetClass+#root.methodName+#id", condition ="#id<30" )
重新运行
发生会查询数据库,不走缓存。 即使Redis里面有这个 key
unless 表示条件不满足时,使用缓存
@Override @Cacheable(value = KEY_PRE,key="#root.targetClass+#root.methodName+#id", unless ="#id<30" ) public User findById(int id) { return userMapper.findById(id); }
三.二 @CachePut 缓存更新
常用于修改缓存里面的内容。
设置 id=40 的用户的缓存, key为: user_::40
@Override @Cacheable(value = KEY_PRE,key="#id" ) public User findById(int id) { return userMapper.findById(id); }
修改用户的信息, 注意, 这个修改方法有返回值 User, 并不是以前的 void
@Override @CachePut(value = KEY_PRE,key = "#user.id") public User updateUser(User user) { userMapper.updateUser(user); //更新全部的缓存信息 return user; }
将返回值 放置到缓存里面。
@Test public void updateTest(){ User user=userService.findById(40); //id随时更换 user.setName("我换新的名字了"); userService.updateUser(user); log.info("修改成功{}",user); findByIdTest();; }
运行处理
发现缓存里面的内容 也同步进行更新了.
添加方法时
注意, 方法有返回值, 为 User userMapper.addUser() 方法,会自动回显 id.
所以 key值用的是 #result 结果里面的id
@CachePut(value=KEY_PRE,key = "#result.id") @Override public User addUser(User user) { userMapper.addUser(user); return user; }
测试方法
@Test public void insertTest(){ //1. 构建对象 User user=new User(); user.setName("岳泽霖"); user.setAge(26); user.setSex("男"); user.setDescription("一个快乐的程序员"); //2. 添加方法 userService.addUser(user); log.info("添加成功,{}",user); }
查看控制台输出
新添加的 用户 id 为56
根据 id=56 查询的话, 也是直接从缓存里面获取数据.