网课142P-155P主要在讲解Redis的基本操作和java集成Redis的方法(Jedis -> Spring Date Redis)
为了方便起见,而且此前已在ssm中学习和集成过,直接进入瑞吉外卖优化阶段。
创建分支v1.0:方便管理
Redis:
引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
导入RedisConfig类:
\瑞吉外卖-资料\5 瑞吉外卖项目优化篇\5 瑞吉外卖项目优化篇\资料\day01\RedisConfig.java
用于指定序列化器
缓存短信验证码:
![](https://img-blog.csdnimg.cn/img_convert/4cd2194c5143d6863f495d71d792f293.png)
// UserController.java
@PostMapping("/sendMail")
public R<String> sendMail(@RequestBody User user, HttpSession session){
...
// 保存验证码,用于检验用户输入的是否正确
session.setAttribute(mailAds, code);
// 缓存验证码,过期时间设为5分钟
redisTemplate.opsForValue().set(mailAds, code, 5, TimeUnit.MINUTES);
...
}
// UserController.java
@PostMapping("/login")
public R<User> login(@RequestBody Map<String, String> map, HttpSession session){
...
// 获取发出的code
// String codeInSession = session.getAttribute(mailAds).toString();
String codeInSession = redisTemplate.opsForValue().get(mailAds);
...
// 用户登录成功,删除缓存的验证码
redisTemplate.delete(mailAds);
session.setAttribute("user", user.getId());
...
}
一个问题:
我在导入maven的spring-boot-starter-data-redis依赖时maven总是在spring-data-keyvalue-2.4.8处爆红线,并且提示Cannot resolve org.springframework.data:spring-data-keyvalue:2.4.8
我找了两个小时终于找到解决办法了:(3条消息) Maven 本地仓库明明有对应的jar包但还是报找不到_本地仓库有jar包 pom却提示找不到_小匠杨的博客-CSDN博客
把\apache-maven-3.6.3-bin\apache-maven-3.6.3\maven-repo\org\springframework\data\spring-data-keyvalue\2.4.8这个目录下的_remote.repositories文件修改为:
spring-data-keyvalue-2.4.8.pom>central=
spring-data-keyvalue-2.4.8.pom>nexus-aliyun=
spring-data-keyvalue-2.4.8.jar>nexus-aliyun=
然后重新加载依赖就好了
测试成功:
![](https://img-blog.csdnimg.cn/img_convert/52c4b47d207c43b1cced4946fc9c65e9.png)
缓存菜品数据:
![](https://img-blog.csdnimg.cn/img_convert/1221a68e7f252db901642311d64e2c86.png)
// DishController.java
@GetMapping("/list")
public R<List<DishDto>> list(Dish dish){
// 拼key
String key = "dish_" + dish.getCategoryId() + "_" + dish.getStatus();
List<DishDto> dishDtos = (List<DishDto>) redisTemplate.opsForValue().get(key);
if (dishDtos != null){
return R.success(dishDtos);
}
...
// 将查出的list缓存到redis
redisTemplate.opsForValue().set(key, dishDtoList, 60, TimeUnit.MINUTES);
return R.success(dishDtoList);
}
更改时清除缓存:
save, updateStatus, update
![](https://img-blog.csdnimg.cn/img_convert/9a5589603b83bcd84fcbd8cee9974344.png)
String key = "dish_" + dishDto.getCategoryId() + "_1";
redisTemplate.delete(key);
Spring Cache:
![](https://img-blog.csdnimg.cn/img_convert/07062a3e2b4817e5d50ebc4b7557297f.png)
所以要在Controller里自动注入一个CacheManager属性
常用注解:
![](https://img-blog.csdnimg.cn/img_convert/05468ff2e9ec19f20696300cb366ffd8.png)
@Cacheable | 标识查询方法 | Get |
@CachePut | 标识新增方法 | Post |
@CacheEvict | 标识删除、更新方法 | Delete、Put |
注解参数:
是通过注解的参数确定注解的动作对象(缓存中的key)
value | 缓存名,相同表示一类缓存,同一缓存名下有多个缓存,相互用key区分 |
key | 支持SpEL,来动态获取方法的返回值(#result)、参数(#参数名)、各种信息(#root) 两个变量指定key时:"#user.id + '_' + #user.name" |
condition | 调用方法前判断,缓存的条件,支持SqEL,其实是一个返回布尔值的字符串,可以防止缓存穿透 |
unless | 执行方法后判断,不缓存的条件 |
因为condition是调用前判断,调用前不可能获得方法的返回值,所以不能用#result,应改用unless属性判断返回值
切换缓存产品:
默认缓存产品是ConcurrentMapCache,本质是一个Map,程序停掉则缓存丢失
SpringCache的redis实现是在spring-boot-starter-data-redis中
![](https://img-blog.csdnimg.cn/img_convert/52f1bda8696139450944dc20e3b306f6.png)
time-to-live单位是毫秒
缓存套餐数据:
![](https://img-blog.csdnimg.cn/img_convert/45ce2fb2e015ddda3bc5cfb84e172092.png)
@Cacheable(value = "setMealCache", key = "#setMeal.categoryId + '_' + #setMeal.status")
注意要让R类实现序列化接口Serializable
删除/更新时删除缓存:
删除时清空所有套餐缓存
@CacheEvict(value = "setMealCache", allEntries = true)
至于能否仅将list参数中的id对应的缓存删掉,我没找到方法