Controller
package com.zsh.controller.user;
@RestController("userDishController")
@RequestMapping("/user/dish")
@Slf4j
@Api(tags = "C端-菜品浏览接口")
public class DishController {
@Autowired
private DishService dishService;
@Autowired
private RedisTemplate redisTemplate;
/**
* 根据分类id查询菜品
*
* @param categoryId
* @return
*/
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result> list(Integer categoryId) {
// 查询
List dishVO = dishService.findByCategoryId(categoryId);
// 返回结果
return Result.success(dishVO);
}
}
ServiceImpl
package com.zsh.service.impl;
import java.util.List;
import java.util.Set;
@Service
public class DishServiceImpl implements DishService {
@Autowired
private DishMapper dishMapper;
@Autowired
private DishFlavorMapper dishFlavorMapper;
@Autowired
private SetmealDishMapper setmealDishMapper;
@Autowired
private RedisTemplate redisTemplate;
/**
* 新增菜品
* @param dishDTO
*/
@Transactional
@Override
public void addDish(DishDTO dishDTO) {
// 创建新增需要用到的对象
Dish dish = new Dish();
// 拷贝对象
BeanUtils.copyProperties(dishDTO,dish);
// 新增菜品
dishMapper.addDish(dish);
// 获取insert语句生成的主键值
Long dishId = dish.getId();
// 取出前台传过来的口味表数据
List flavors = dishDTO.getFlavors();
// 判断前端前台是否添加了口味表数据
if(flavors != null && flavors.size() > 0){
flavors.forEach(flavor -> {
flavor.setDishId(dishId);
});
}
// 新增口味
dishFlavorMapper.addDishFlavor(flavors);
}
/**
* 菜品分页查询
* @param dishPageQueryDTO
* @return
*/
@Override
public PageResult pageDish(DishPageQueryDTO dishPageQueryDTO) {
// 开启分页查询
PageHelper.startPage(dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize());
// 条件查询
List list = dishMapper.pageDish(dishPageQueryDTO);
// 获取分页结果
Page page = (Page) list;
// 封装结果
PageResult pageResult = new PageResult(page.getTotal(),page.getResult());
return pageResult;
}
/**
* 根据id查询菜品
* @param id
* @return
*/
@Override
public DishVO findByIdDish(Integer id) {
// 查询菜品
Dish dish = dishMapper.findById(id);
// 根据菜品id查询口味
List flavors = dishFlavorMapper.findByDishId(id);
// 封装返回结果
DishVO dishVO = new DishVO();
// 拷贝对象
BeanUtils.copyProperties(dish,dishVO);
// 给对象的属性赋值
dishVO.setFlavors(flavors);
// 返回结果
return dishVO;
}
/**
* 修改菜品
* @param dishDTO
*/
@Override
@Transactional
public void updateDish(DishDTO dishDTO) {
// 创建修改需要用到的对象
Dish dish = new Dish();
// 拷贝对象
BeanUtils.copyProperties(dishDTO,dish);
// 修改菜品
dishMapper.updateDish(dish);
// 删除口味
dishFlavorMapper.deleteByDishId(dishDTO.getId());
// 取出修改后的口味数组
List flavors = dishDTO.getFlavors();
// 判断口味是否修改
if(flavors != null && flavors.size()>0){
// 遍历将id放数组
flavors.forEach(flavor -> {
flavor.setDishId(dishDTO.getId());
});
// 添加新的口味
dishFlavorMapper.addDishFlavor(flavors);
}
//将所有的菜品缓存数据清理掉,所有以dish_开头的key
cleanCache("dish_*");
}
/**
* 批量删除菜品
* @param ids
*/
@Transactional
@Override
public void deleteDish(List ids) {
// 判断菜品是否起售,如果起售则不删除
for (Integer id : ids) {
// 根据id查询菜品
Dish dish = dishMapper.findById(id);
// 判断菜品是否起售
if (dish.getStatus() == StatusConstant.ENABLE) {
throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
}
}
// TODO这里要判断菜品是否被套餐关联,关联则不能删除
List list = setmealDishMapper.findByDishId(ids);
if(list != null && list.size() > 0){
throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
}
for (Integer id : ids) {
// 删除菜品
dishMapper.deleteById(id);
// 删除口味
dishFlavorMapper.deleteByDishId(Long.valueOf(id));
}
// 将所有的菜品缓存数据清理掉,所有以dish_开头的key
cleanCache("dish_*");
}
/**
* 菜品起售、停售
* @param status
* @param id
*/
@Override
public void okAndNo(Integer status, Integer id) {
// 创建修改要用到的对象
Dish dish = new Dish();
// 设置状态
dish.setStatus(status);
// 设置id
dish.setId(Long.valueOf(id));
// 修改
dishMapper.updateDish(dish);
// 将所有的菜品缓存数据清理掉,所有以dish_开头的key
cleanCache("dish_*");
}
/**
* 根据分类id查询菜品
* @param categoryId
* @return
*/
@Override
public List findByCategoryId(Integer categoryId) {
// 构造redis中的key,规则dish_分类id
String key = "dish_"+ categoryId;
// 查询redis中是否存在菜品数据
List redisList = (List) redisTemplate.opsForValue().get(key);
// 判断redis数据库是否存在数据,存在则无序查询mysql
if(redisList != null && redisList.size() > 0){
return redisList;
}
// 查询MySQL数据库
List list = dishMapper.findByCategoryId(categoryId);
// 获取菜品id
for (DishVO dish : list) {
// 根据菜品id查询菜品口味
List disFlavor = dishFlavorMapper.findByDishId(Math.toIntExact(dish.getId()));
// 将口味放入对应的菜品
dish.setFlavors(disFlavor);
}
// 如果redis数据库中没有查到数据,就把查到的数据保存到数据库
redisTemplate.opsForValue().set(key,list);
// 返回结果
return list;
}
/**
* 清理缓存数据
* @param pattern
*/
private void cleanCache(String pattern){
Set keys = redisTemplate.keys(pattern);
redisTemplate.delete(keys);
}
}
Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
1、 导入Spring Cache和Redis相关maven坐标
org.springframework.boot
spring-boot-starter-data-redis
org.springframework.boot
spring-boot-starter-cache
2、在启动类上加入@EnableCaching注解,开启缓存注解功能
package com.zsh;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@EnableTransactionManagement //开启注解方式的事务管理
@Slf4j
@EnableCaching
public class SkyApplication {
public static void main(String[] args) {
SpringApplication.run(SkyApplication.class, args);
log.info("server started");
}
}
3、在用户端接口SetmealController的 list 方法上加入@Cacheable注解
/**
* 条件查询
*
* @param categoryId
* @return
*/
@GetMapping("/list")
@ApiOperation("根据分类id查询套餐")
@Cacheable(cacheNames = "setmealCache",key = "#categoryId") //key: setmealCache::100
public Result> list(Long categoryId) {
Setmeal setmeal = new Setmeal();
setmeal.setCategoryId(categoryId);
setmeal.setStatus(StatusConstant.ENABLE);
List list = setmealService.list(setmeal);
return Result.success(list);
}
4、在管理端接口SetmealController的 save、delete、update、startOrStop等方法上加入CacheEvict注解
/**
* 新增套餐
*
* @param setmealDTO
* @return
*/
@PostMapping
@ApiOperation("新增套餐")
@CacheEvict(cacheNames = "setmealCache",key = "#setmealDTO.categoryId")//key: setmealCache::100
public Result save(@RequestBody SetmealDTO setmealDTO) {
setmealService.saveWithDish(setmealDTO);
return Result.success();
}
/**
* 批量删除套餐
*
* @param ids
* @return
*/
@DeleteMapping
@ApiOperation("批量删除套餐")
@CacheEvict(cacheNames = "setmealCache",allEntries = true)
public Result delete(@RequestParam List ids) {
setmealService.deleteBatch(ids);
return Result.success();
}
/**
* 修改套餐
*
* @param setmealDTO
* @return
*/
@PutMapping
@ApiOperation("修改套餐")
@CacheEvict(cacheNames = "setmealCache",allEntries = true)
public Result update(@RequestBody SetmealDTO setmealDTO) {
setmealService.update(setmealDTO);
return Result.success();
}
/**
* 套餐起售停售
*
* @param status
* @param id
* @return
*/
@PostMapping("/status/{status}")
@ApiOperation("套餐起售停售")
@CacheEvict(cacheNames = "setmealCache",allEntries = true)
public Result startOrStop(@PathVariable Integer status, Long id) {
setmealService.startOrStop(status, id);
return Result.success();
}