苍穹外卖--缓存菜品
1.问题说明
用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大
2.实现思路
通过Redis来缓存菜品数据,减少数据库查询操作。
缓存逻辑分析:
①每个分类下的菜品保持一份缓存数据
②数据库中菜品数据有变更时清理缓存数据
3.代码开发
user/DishController.java代码:
@Autowiredprivate RedisTemplate redisTemplate;
@GetMapping("/list")@ApiOperation("根据分类id查询菜品")public Result<List<DishVO>> list(Long categoryId) {//构造redis中的key,规则:dish_分类idString key = "dish_" + categoryId;//查询redis中是否存在菜品数据List<DishVO> list = (List<DishVO>) redisTemplate.opsForValue().get(key);if(list != null && list.size() > 0){//如果存在,直接返回,无须查询数据库return Result.success(list);}Dish dish = new Dish();dish.setCategoryId(categoryId);dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品//如果不存在,查询数据库,将查询的数据放入redis中list = dishService.listWithFlavor(dish);redisTemplate.opsForValue().set(key,list);return Result.success(list);}
admin/DishController.java代码:
package com.sky.controller.admin;import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;import java.util.List;
import java.util.Set;/*** 菜品管理*/
@RestController
@RequestMapping("/admin/dish")
@Api(tags = "菜品管理接口")
@Slf4j
public class DishController {@Autowiredprivate DishService dishService;@Autowiredprivate RedisTemplate redisTemplate;/*** 新增菜品* @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();}/*** 菜品分页查询* @param dishPageQueryDTO* @return*/@GetMapping("/page")@ApiOperation("菜品分页查询")public Result<PageResult> page(DishPageQueryDTO dishPageQueryDTO){//分页查询统一返回的是PageResult,因为返回的是Query,所以不需要注解接受PageResult pageResult = dishService.pageQuery(dishPageQueryDTO);return Result.success(pageResult);}/*** 菜品批量删除* @param ids* @return*/@DeleteMapping@ApiOperation("菜品批量删除")public Result delete(@RequestParam List<Long> ids){//使用SpringMVC中的@RequestParam来将数据分割成集合log.info("菜品批量删除:{}",ids);dishService.deleteBatch(ids);//将所有的菜品缓存数据清理掉,所有dish_开头的keycleanCache("dish_*");return Result.success();}/*** 根据id查询菜品* @return*/@GetMapping("/{id}")@ApiOperation("根据id查询菜品")public Result<DishVO> getById(@PathVariable Long id){log.info("根据id查询菜品:{}",id);DishVO dishVO = dishService.getByIdWithFlavor(id);return Result.success(dishVO);}/*** 修改菜品* @param dishDTO* @return*/@PutMapping@ApiOperation("修改菜品")public Result update(@RequestBody DishDTO dishDTO){log.info("修改菜品:{}",dishDTO);dishService.updateWithFlavor(dishDTO);//将所有的菜品缓存数据清理掉,所有dish_开头的keycleanCache("dish_*");return Result.success();}/*** 菜品起售停售* @param status* @param id* @return*/@PostMapping("/status/{status}")@ApiOperation("菜品起售停售")public Result<String> startOrStop(@PathVariable Integer status, Long id){dishService.startOrStop(status,id);//将所有的菜品缓存数据清理掉,所有dish_开头的keycleanCache("dish_*");return Result.success();}/*** 根据分类id查询菜品* @param categoryId* @return*/@GetMapping("/list")@ApiOperation("根据分类id查询菜品")public Result<List<Dish>> list(Long categoryId){List<Dish> list = dishService.list(categoryId);return Result.success(list);}/*** 清理缓存数据* @param pattern*/private void cleanCache(String pattern){Set keys = redisTemplate.keys(pattern);redisTemplate.delete(keys);}
}