1、为什么要缓存?
对于热点数据,如果都直接访问数据库会造成数据库压力过大
2、解决
因此为了解决这一问题,通过redis来缓存热点数据
这样访问热点数据时先去redis中查找,如果存在则返回,如果不存在再访问数据库并将数据缓存到redis
注意:只缓存user端的查询,因为管理端的访问比较少
Controller层
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result<List<DishVO>> list(Long categoryId) {
/*
1、先去redis中根据categoryId获取缓存数据,如果存在直接返回,不存在则查询数据库
2、查询数据库,将查询到的数据保存到redis中,返回
*/
String key = "dish_"+categoryId;
List<DishVO> list = (List<DishVO>) redisTemplate.opsForValue().get(key);
if(list == null){
Dish dish = new Dish();
dish.setCategoryId(categoryId);
dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品
list = dishService.listWithFlavor(dish);
if(list != null && list.size() > 0){
redisTemplate.opsForValue().set(key,list);
}
}
return Result.success(list);
}
3、存在问题
此时如果数据库更改了数据,但是redis缓存中没有修改为最新数据,由于用户访问还是会先访问redis且其中也存在数据,则会访问到旧的错误数据。这就导致了数据一致性的问题
解决方案:
1、增量同步:数据库增删改什么数据,redis就增删改什么数据
2、全量同步:删除redis中所有数据再全部重新添加(推荐)
全量同步:
思路:当管理端增、删、改数据操作时将redis中所有缓存删除,这样下次用户第一次查询时会直接访问数据库,并将数据库中数据缓存到redis
/**
* 批量删除菜品
* @param ids
* @return
*/
@ApiOperation("批量删除接口")
@DeleteMapping()
public Result deleteByIds(@RequestParam List<Integer> ids){
log.info("批量删除操作");
dishService.deleteByIds(ids);
//清空所有缓存dish数据
String key = "dish_*";
Set keys = redisTemplate.keys(key);
redisTemplate.delete(keys);
return Result.success();
}