<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
我的redis直接装在了windows上,所以host为本地地址。安装方法看此博客:https://www.redis.com.cn/redis-installation.html
在config目录下创建RedisConfig
类,
这里不推荐把value也设置成StringRedisSerializer,如果设置成StringRedisSerializer,后面向redis中存入集合时会发生转换异常。
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
//默认的Key序列化器为:JdkSerializationRedisSerializer
redisTemplate.setKeySerializer(new StringRedisSerializer()); // key序列化
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}
提交并推送到github,签名:redis环境配置。注意分支为 v1.0
安装一个redis可视化界面进行测试,我使用的是Another Redis Desktop Manager
提交并推送代码,签名:缓存短信验证码。
/**
* 根据条件查询对应的菜品数据
*
* @param dish
* @return
*/
@GetMapping("/list")
public R<List<DishDto>> list(Dish dish) {
List<DishDto> dishDtoList = null;
String key = "dish_" + dish.getCategoryId() + "_" + dish.getStatus();
// 先从redis获取数据
dishDtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);
if (dishDtoList != null) {
// 如果redis中有数据则直接返回
return R.success(dishDtoList);
}
// 构造查询条件
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
// 查询状态为1的菜品
queryWrapper.eq(Dish::getStatus, 1);
// 添加排序条件
queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
List<Dish> list = dishService.list(queryWrapper);
dishDtoList = list.stream().map(item -> {
DishDto dishDto = new DishDto();
// 拷贝属性
BeanUtils.copyProperties(item, dishDto);
// 设置DishDto分类名称属性
Long categoryId = item.getCategoryId();
Category category = categoryService.getById(categoryId);
if (category != null) {
String categoryName = category.getName();
dishDto.setCategoryName(categoryName);
}
// 设置菜品口味
Long dishId = item.getId();
LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
dishFlavorLambdaQueryWrapper.eq(DishFlavor::getDishId, dishId);
// SQL: select * from dish_flavor where dish_id = ?
List<DishFlavor> dishFlavorList = dishFlavorService.list(dishFlavorLambdaQueryWrapper);
dishDto.setFlavors(dishFlavorList);
return dishDto;
}).collect(Collectors.toList());
// 将数据存入redis
redisTemplate.opsForValue().set(key, dishDtoList, 60, TimeUnit.MINUTES);
return R.success(dishDtoList);
}
/**
* 修改菜品
* @param dishDto
* @return
*/
@PutMapping
public R<String> update(@RequestBody DishDto dishDto) {
log.info(dishDto.toString());
dishService.updateWithFlavor(dishDto);
// 清理所有菜品的缓存数据
// Set keys = redisTemplate.keys("dish_*");
// redisTemplate.delete(keys);
// 清理某个分类下面的菜品缓存数据
String key = "dish_" + dishDto.getCategoryId() + "_1";
redisTemplate.delete(key);
return R.success("修改菜品成功");
}
/**
* 新增菜品
* @param dishDto
* @return
*/
@PostMapping
public R<String> save(@RequestBody DishDto dishDto) {
log.info(dishDto.toString());
dishService.saveWithFlavor(dishDto);
// 清理所有菜品的缓存数据
// Set keys = redisTemplate.keys("dish_*");
// redisTemplate.delete(keys);
// 清理某个分类下面的菜品缓存数据
String key = "dish_" + dishDto.getCategoryId() + "_1";
redisTemplate.delete(key);
return R.success("新增菜品成功");
}
/**
* 逻辑删除
* @param ids
* @return
*/
@DeleteMapping
@Transactional
public R<String> delete(Long[] ids) {
log.info("批量删除的id:{}", Arrays.toString(ids));
// 先逻辑删除菜品对应的口味信息
dishFlavorService.removeByDishIds(Arrays.asList(ids));
// 在逻辑删除菜品
dishService.removeByIds(Arrays.asList(ids));
// 清理所有菜品的缓存数据
// Set keys = redisTemplate.keys("dish_*");
// redisTemplate.delete(keys);
// 根据dishId集合查询出categoryId集合
List<Dish> dishes = dishService.listByIds(Arrays.asList(ids)); // 查询所有id在ids里的dish记录
Set<Long> categoryIds = dishes.stream().map(Dish::getCategoryId).collect(Collectors.toSet());// 取出字段category_id集合,set集合防止重复
// 清除所有id在categoryIds中的缓存
categoryIds.forEach(item -> {
String key = "dish_" + item + "_1";
redisTemplate.delete(key);
});
return R.success("删除菜品成功");
}
提交并推送代码,签名:缓存菜品。分支:v1.0
将 v1.0 分支的代码合并到主分支上
之前已经导入了redis的相关依赖,现在只需要导入spring cache:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
在启动类上标注@EnableCaching
注解
public class R<T> implements Serializable
1、修改SetmealController
里的list
方法
/**
* 根据分类id和状态查询套餐
* @param setmeal
* @return
*/
@GetMapping("/list")
@Cacheable(value = "setmealCache", key = "#setmeal.categoryId + '_' + #setmeal.status")
public R<List<Setmeal>> list(Setmeal setmeal) {
LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId());
queryWrapper.eq(setmeal.getStatus() != null, Setmeal::getStatus, setmeal.getStatus());
queryWrapper.orderByDesc(Setmeal::getUpdateTime);
List<Setmeal> list = setmealService.list(queryWrapper);
return R.success(list);
}
2、给SetmealController
下的delete
、save
、update
方法都标上以下注解
@CacheEvict(value = "setmealCache", allEntries = true)
手机界面登陆后点击套餐查询,查看效果
提交并推送代码,签名:spring cache缓存套餐数据。分支:v1.0
合并步骤: