我们来看主要的流程
很简单,就是在数据库和接口之间加了一层缓冲,在redis之前其实还可以加其他的缓存 例如 nginx的缓存
接下来,就是结合我的业务,来做缓存
我这里的业务逻辑是,按了分类的按钮,分别以不同的 分类为一组缓存数据
所以,这里的缓存粒度是分类
我设计的id如下
public class RedisContants {
//用户端--------------------------------
//分类下的菜品缓存
public static final String DISH_CATEGORY = "dish:category:";
}
为了体现粒度,我们操作redis key的时候,加上分类id
我们来看我已经写好的样子
我们需要改造的地方有几处
第一:
通过分类id获得此分类下的菜品的时候,我们要保存redis
第二:
当我们修改菜品,不管是添加 + 删除 + 修改,都要修改这里的代码
我在想其实,这里会有写耦合,redis的操作 + 数据库的操作,如果我们可以分离出来就完美了
redis的工具类在我另外一个博客里边
https://blog.csdn.net/weixin_52232901/article/details/135850329
@RestController("userDishController")
@RequestMapping("/user/dish")
@Slf4j
@Api(tags = "菜品管理")
public class DishController {
@Autowired
private DishService dishService;
@Autowired
private RedisCache redisCache;
@ApiOperation("根据分类id查询菜品")
@GetMapping("/list")
public Result getByCategoryId(Long categoryId) {
log.info("根据分类id查询菜品 参数为{}",categoryId);
//先去redis中查
List<DishVO> dishVOs = redisCache.getCacheObject(RedisContants.DISH_CATEGORY + categoryId);
if(dishVOs != null && dishVOs.size() > 0) {
return Result.success(dishVOs);
}
//没查到redis,去mysql查,并且更新redis,设置一天的时间为过期时间
dishVOs = dishService.getByCategoryIdUser(categoryId);
redisCache.setCacheObject(RedisContants.DISH_CATEGORY + categoryId,dishVOs,
RedisContants.DISH_CATEGORY_TTL,
RedisContants.DISH_CATEGORY_TIMEUNIT);
return Result.success(dishVOs);
}
}
public static final String DISH_CATEGORY = "dish:category:";
public static final Integer DISH_CATEGORY_TTL = 24;
public static final TimeUnit DISH_CATEGORY_TIMEUNIT = TimeUnit.HOURS;
这里的修改,你们可以不用看,这里只是我的业务有相关性,所以记录下来
/**
* 员工管理
*/
@RestController
@RequestMapping("/admin/dish")
@Slf4j
@Api(tags = "菜品管理")
public class DishController {
@Autowired
private DishService dishService;
@Autowired
private RedisCache redisCache;
@ApiOperation("分页查询")
@GetMapping("/page")
public Result<PageResult> pageQuery(DishPageQueryDTO dishPageQueryDTO) {
log.info("分页查询 参数为{}",dishPageQueryDTO);
PageResult page = dishService.pageQuery(dishPageQueryDTO);
return Result.success(page);
}
@ApiOperation("根据id查询菜品")
@GetMapping("/{id}")
public Result getByid(@PathVariable Long id) {
log.info("根据id查询菜品 参数为{}",id);
DishVO dish = dishService.getByid(id);
return Result.success(dish);
}
@ApiOperation("根据分类id查询菜品")
@GetMapping("/list")
public Result getByCategoryId(Long categoryId) {
log.info("根据分类id查询菜品 参数为{}",categoryId);
List<Dish> dish = dishService.getByCategoryId(categoryId);
return Result.success(dish);
}
@ApiOperation("修改菜品")
@PutMapping
public Result<PageResult> update(@RequestBody DishDTO dishDTO) {
log.info("修改菜品 参数为{}",dishDTO);
dishService.updateDish(dishDTO);
//删除缓存
redisCache.deleteObject(RedisContants.DISH_CATEGORY + dishDTO.getCategoryId());
return Result.success();
}
@ApiOperation("新增菜品")
@PostMapping
public Result<PageResult> add(@RequestBody DishDTO dishDTO) {
log.info("新增菜品 参数为{}",dishDTO);
dishService.addDish(dishDTO);
//删除缓存
redisCache.deleteObject(RedisContants.DISH_CATEGORY + dishDTO.getCategoryId());
return Result.success();
}
@ApiOperation("修改状态")
@PostMapping("/status/{status}")
public Result changeStatus(@PathVariable Integer status,Long id) {
log.info("修改状态 参数为{},{}",status,id);
dishService.changeStatus(status,id);
Dish dish = dishService.getById(id);
//删除缓存
redisCache.deleteObject(RedisContants.DISH_CATEGORY + dish.getCategoryId());
return Result.success();
}
@ApiOperation("删除菜品")
@DeleteMapping
public Result delete(String ids) {
log.info("删除菜品 参数为{}",ids);
String[] split = ids.split(",");
List<Long> list = Arrays.stream(split)
.map((str) -> Long.parseLong(str)).collect(Collectors.toList());
dishService.deleteById(list);
Collection<String> keys = redisCache.keys(RedisContants.DISH_CATEGORY + "*");
//删除所有的菜品
redisCache.deleteObject(keys);
return Result.success();
}
}
这里按道理来说,其实还是要给redis这样的key要至少设置时间才行,不然就会有问题
我这里的修改,比较要注意的是,我这里的keys,我在批量删除的时候,我的业务逻辑是,直接所有的缓存都删除
也就是以 dish:category:分类id,开头的所有都要删除,所以我们需要得到所有这样的keys的集合,也就是
Collection<String> keys = redisCache.keys(RedisContants.DISH_CATEGORY + "*");
通过这个,然后直接删除,通过集合的方式,直接删除