Redis直接缓存
对于分类查询操作而言,在用户端这个接口需要频繁被调用,所以可以以分类id为key,菜品为值来存在redis当中
java
/**
* 根据分类id查询菜品
*
* @param categoryId
* @return
*/
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result<List<DishVO>> list(Long categoryId) {
// 构造Redis的key
String key ="dish_"+categoryId;
List<DishVO> list = (List<DishVO>) redisTemplate.opsForValue().get(key);
// 查询Redis中是否存在菜品数据
if(list!=null && list.size()>0){
// 存在,直接返回缓存中的数据
return Result.success(list);
}
// 不存在,查询数据库
Dish dish = new Dish();
dish.setCategoryId(categoryId);
dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品
list = dishService.listWithFlavor(dish);
// 缓存数据
redisTemplate.opsForValue().set(key,list);
return Result.success(list);
}
对于管理端拥有的增删改三个操作,如果在数据库层面改了,缓存没有清理,就会导致用户读到的是脏数据,所以在进行三类操作时需要清理掉缓存数据
封装一个清理的函数
java
/**
* 清理缓存
* @param pattern
*/
private void cleanCache(String pattern){
Set keys = redisTemplate.keys(pattern);
redisTemplate.delete(keys);
}
在删改操作中直接调用
java
/**
* 批量删除
* @param ids
* @return
*/
@DeleteMapping
@ApiOperation("菜品批量删除")
public Result delete(@RequestParam List<Long> ids){
log.info("菜品批量删除:{}",ids);
dishService.deleteBatch(ids);
// 清理缓存
cleanCache("dish_*");
return Result.success();
}
/**
* 更新菜品
* @param dishDTO
* @return
*/
@PutMapping
@ApiOperation("更新菜品")
public Result update(@RequestBody DishDTO dishDTO){
log.info("更新菜品:{}",dishDTO);
dishService.updateWithFlavor(dishDTO);
// 清理缓存
cleanCache("dish_*");
return Result.success();
}
/**
* 起售、停售菜品
* @param status
* @param id
* @return
*/
@PostMapping("/status/{status}")
@ApiOperation("起售、停售菜品")
public Result startOrStop(@PathVariable Integer status,Long id){
log.info("起售、停售菜品:{}",id);
dishService.startOrStop(status,id);
// 清理缓存
cleanCache("dish_*");
return Result.success();
}
在上述操作中因为涉及到多个菜品需要更新(删除操作,他们可能处于同一个分类也可能处于不同分类)或是更新菜品时可能是更新分类id,这样的时候都需要先查询了,得不偿失,可以直接清楚所有的分类缓存
增加菜品时直接只更新相应的分类id即可
java
/**
* 新增菜品
* @param dishDTO
* @return
*/
@PostMapping
@ApiOperation("添加菜品")
public Result save(@RequestBody DishDTO dishDTO){
log.info("添加菜品:{}",dishDTO);
dishService.saveWithFlavor(dishDTO);
// 清理缓存
String key = "dish_" + dishDTO.getCategoryId();
cleanCache(key);
return Result.success();
}
Spring Cache


注解使用
EnableCaching
java
@Slf4j
@SpringBootApplication
@EnableCaching // 开启缓存功能
public class CacheDemoApplication {
public static void main(String[] args) {
SpringApplication.run(CacheDemoApplication.class,args);
log.info("项目启动成功...");
}
}
CachePut
java
@PostMapping
@CachePut(cacheNames = "userCache",key = "#user.id") //如果使用Spring Cache缓存数据,key的生成为:userCache::id, 从形参获取参数
//@CachePut(cacheNames = "user",key = "#result.id") // 对象导航,从返回值获取参数
//@CachePut(cacheNames = "user",key = "#p0") // 使用参数位置,从第一个参数获取参数
//@CachePut(cacheNames = "user",key = "#a0") // 使用参数位置,从第一个参数获取参数
//@CachePut(cacheNames = "user",key = "root.arg[0].id") // 使用参数位置,从第一个参数获取参数
public User save(@RequestBody User user){
userMapper.insert(user);
return user;
}
Cacheable
java
@GetMapping
@Cacheable(cacheNames = "userCache",key = "#id") // key生成 userCache::2
public User getById(Long id){
User user = userMapper.getById(id);
return user;
}
CacheEvict
java
@DeleteMapping
@CacheEvict(cacheNames = "userCache",key = "#id") // key生成 userCache::2
public void deleteById(Long id){
userMapper.deleteById(id);
}
@DeleteMapping("/delAll")
@CacheEvict(cacheNames = "userCache",allEntries = true) // 删除所有缓存userCache::*
public void deleteAll(){
userMapper.deleteAll();
}
在项目中的使用思路
