缓存套餐数据
SetmealController的list方法,此方法会根据前端提交的查询条件进行数据库查询操作。在高并发的情况下,频繁查询数据库会导致系统性能下降,服务端响应时间增长。
对此方法进行缓存优化,提高系统的性能:
1、导入Spring Cache和Redis相关maven坐标
2、在application.yml中配置缓存数据的过期时间
3、在启动类上加入@EnableCaching注解,开启缓存注解功能
4、在SetmealController的list方法上加入@Cacheable注解
5、在SetmealController的save和update方法上加入CacheEvict注解
package com.itheima.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.itheima.common.R; import com.itheima.dto.SetmealDto; import com.itheima.entity.Category; import com.itheima.entity.Dish; import com.itheima.entity.Setmeal; import com.itheima.entity.SetmealDish; import com.itheima.service.CategoryService; import com.itheima.service.DishService; import com.itheima.service.SetmealDishService; import com.itheima.service.SetmealService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.stream.Collectors; /** * 套餐管理 */ @RestController @RequestMapping("/setmeal") @Slf4j public class SetmealController { @Autowired private SetmealService setmealService; @Autowired private SetmealDishService setmealDishService; @Autowired private CategoryService categoryService; @Autowired private DishService dishService; /** * 新增套餐 * @param setmealDto * 删除缓存里面setmealcache下的数据 * @return */ @PostMapping @CacheEvict(value = "setmealCache", allEntries = true) public R<String> add(@RequestBody SetmealDto setmealDto){ setmealService.saveWithDish(setmealDto); return R.success("新增套餐成功"); } /** * 套餐分页查询 * @param page * @param pageSize * @param name * @return */ @GetMapping("/page") public R<Page> page(int page, int pageSize, String name){ //创建分页构造器 Page<Setmeal> pageInfo = new Page<>(page, pageSize); //创建条件构造器 LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>(); //添加查询条件,根据name进行like模糊查询 queryWrapper.like(name!=null, Setmeal::getName, name); //添加排序条件,根据更新时间降序排列 queryWrapper.orderByDesc(Setmeal::getUpdateTime); setmealService.page(pageInfo, queryWrapper); Page<SetmealDto> dtoPage = new Page(page, pageSize); //对象拷贝,因为pageInfo中的records是Setmeal类型,而dtoPage中的records是SetmealDto类型 BeanUtils.copyProperties(pageInfo, dtoPage, "records"); List<Setmeal> records = pageInfo.getRecords(); //通过category_id查询categoryName List<SetmealDto> list = records.stream().map((item) -> { SetmealDto setmealDto = new SetmealDto(); //对象拷贝 BeanUtils.copyProperties(item, setmealDto); //根据categoryId查询分类对象category Category category = categoryService.getById(item.getCategoryId()); if(category!=null){ setmealDto.setCategoryName(category.getName()); } return setmealDto; }).collect(Collectors.toList()); dtoPage.setRecords(list); return R.success(dtoPage); } /** * 删除套餐:删除一个或者批量删除 * 清理setmealCache套餐下的所有缓存数据 * @param ids * @return */ @DeleteMapping @CacheEvict(value = "setmealCache", allEntries = true) public R<String> delete(@RequestParam List<Long> ids){ // log.info("ids:{}", ids); setmealService.removeWithDish(ids); return R.success("套餐数据删除成功"); } /** * 套餐的启售、停售、批量修改售卖状态 * @return */ @PostMapping("/status/{status}") public R<String> statusChange(@PathVariable int status, @RequestParam List<Long>ids){ List<Setmeal> setmeals = setmealService.listByIds(ids); //若status=1套餐要起售,则先查询该套餐包含的所有菜品的状态是否都为起售 if(status==1){ LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>(); for(Setmeal setmeal : setmeals){ //查询套餐中包含的菜品setmealDish queryWrapper.eq(SetmealDish::getSetmealId, setmeal.getId()); List<SetmealDish> setmealDishes = setmealDishService.list(queryWrapper); //通过setmealDish中的dishId查询该菜品的status=0停售,status=1启售 for(SetmealDish setmealDish : setmealDishes){ Dish dish = dishService.getById(setmealDish.getDishId()); //dish.status=0表示该菜品处于停售,因此包含该菜品的套餐setmeal无法更改售卖状态 if(dish.getStatus()==0){ return R.error("套餐状态修改失败,该套餐中存在餐品为停售状态"); } } } } for(Setmeal setmeal : setmeals){ setmeal.setStatus(status); } setmealService.updateBatchById(setmeals); return R.success("状体修改成功"); } /** * 根据id查询套餐信息和包含的菜品信息 * 修改时回显数据 * @param id * @return */ @GetMapping("/{id}") public R<SetmealDto> get(@PathVariable Long id){ SetmealDto setmealDto = setmealService.getByIdWithDish(id); return R.success(setmealDto); } /** *根据条件查询套餐数据 * @param setmeal * @return */ @GetMapping("/list") @Cacheable(value = "setmealCache", key = "#setmeal.categoryId + '_' + #setmeal.status") public R<List<Setmeal>> list(Setmeal setmeal){ Long categoryId = setmeal.getCategoryId(); LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(categoryId!=null, Setmeal::getCategoryId, categoryId); queryWrapper.eq(setmeal.getStatus()!=null, Setmeal::getStatus, setmeal.getStatus()); queryWrapper.orderByDesc(Setmeal::getUpdateTime); List<Setmeal> setmeals = setmealService.list(queryWrapper); return R.success(setmeals); } /** * 更新套餐表setmeal和对应的关联菜品信息setmeal_dish * @param setmealDto * @return */ @PutMapping public R<String> update(@RequestBody SetmealDto setmealDto){ setmealService.updateWithSetmealDish(setmealDto); return R.success("套餐更新成功"); } }