菜品的删除
删除数据时,数据库中的表关联了其他表,怎么删除?
1.熟悉业务规则,我们可以先把思路写出来
/* 业务规则: 1.可以一次删除一个菜品,也可以批量删除多个菜品 2.起售中的菜品不能删除 3。被套餐关联的菜品不能删除 4.删除菜品,需要把菜品和口味同时删除 */
2.正常进行三层架构的代码编写
控制层
@DeleteMapping @ApiOperation("菜品批量删除") public Result deleteBatch(@RequestParam List<Long> ids) { //由springmvc框架动态的解析字符串,把id提取出来,封装到集合对象中 log.info("菜品批量删除:{}", ids); dishService.deleteBatch(ids); return Result.success(); }
dishmapperf接口中:
/** * 根据主键删除菜品数据 * @param id */ @Delete("delete from dish where id = #{id}") void deleteById(Long id);
dishFlavorMapper接口中:
/** * 根据菜品Id删除对应口味数据 * @param dishId */ @Delete("delete from dish_flavor where dish_id = #{dishId}") void deleteByDishId(Long dishId); }
SetmealDishMapper使用代码比较繁琐,且我们应该使用动态SQL来保证代码的灵活性,所以使用xml的方式
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.sky.mapper.SetmealDishMapper"> <select id="getSetmealIdsByDishIds" resultType="java.lang.Long"> select setmeal_id from setmeal_dish where dish_id in <foreach collection="dishIds" item="dishId" open="(" close=")" separator=","> #{dishId} </foreach> </select> </mapper>
业务层
/** * 菜品批量删除 * * @param ids */ void deleteBatch(List<Long> ids);
实现层
package com.sky.service.impl; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.sky.constant.MessageConstant; import com.sky.constant.StatusConstant; import com.sky.dto.DishDTO; import com.sky.dto.DishPageQueryDTO; import com.sky.entity.Dish; import com.sky.entity.DishFlavor; import com.sky.exception.DeletionNotAllowedException; import com.sky.mapper.DishFlavorMapper; import com.sky.mapper.DishMapper; import com.sky.mapper.SetmealDishMapper; import com.sky.result.PageResult; import com.sky.service.DishService; import com.sky.vo.DishVO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service @Slf4j public class DishServiceImpl implements DishService { @Autowired private DishMapper dishMapper; @Autowired private DishFlavorMapper dishFlavorMapper; @Autowired private SetmealDishMapper setmealDishMapper; /** * 新增菜品和对应的口味 * @param dishDTO */ @Transactional//事务注解,要么全部成功,要么全部失败 @Override public void saveWithFlavor(DishDTO dishDTO) { //向菜品表插入一条数据 Dish dish = new Dish(); //对象属性拷贝 BeanUtils.copyProperties(dishDTO,dish); dishMapper.insert(dish); //获取insert语句生成的主键值 Long dishId = dish.getId(); List<DishFlavor> flavors = dishDTO.getFlavors(); if (flavors!=null&& flavors.size()>0) { flavors.forEach(item->{ item.setDishId(dishId); }); // 向口味表插入n条数据 dishFlavorMapper.insertBatch(flavors); } } /** * 菜品分页查询 */ @Override public PageResult pageQuery(DishPageQueryDTO dishPageQueryDTO) { PageHelper.startPage(dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize()); Page<DishVO> page = dishMapper.pageQuery(dishPageQueryDTO); return new PageResult(page.getTotal(),page.getResult()); } /** * 菜品批量删除 * * @param ids */ @Override @Transactional//事务注解,要么全部成功,要么全部失败,保证数据的一致性 public void deleteBatch(List<Long> ids) { /* 业务规则: 1.可以一次删除一个菜品,也可以批量删除多个菜品 2.起售中的菜品不能删除 3。被套餐关联的菜品不能删除 4.删除菜品,需要把菜品和口味同时删除 */ //判断当前菜品是否起售 //把id遍历出来,根据id查询菜品数据 for (Long id : ids) { Dish dish = dishMapper.getById(id); //判断菜品是否起售 if (dish.getStatus()== StatusConstant.ENABLE){ //当前菜品在起售中不能删除 throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE); } } //判断当前菜品是否被套餐关联 List<Long> setmealIds = setmealDishMapper.getSetmealIdsByDishIds(ids); if (setmealIds!=null&&setmealIds.size()>0){ //当前菜品被套餐关联,不能删除 throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL); } //创建一个新的mapper来操作关系表,根据菜品id查询套餐id //删除菜品表中的菜品数据 for (Long id : ids) { dishMapper.deleteById(id); //删除菜品关联的口味数据 dishFlavorMapper.deleteByDishId(id); } } }
3.然后在实现类中编写我们需要的代码:
1.其中使用注入的dishMapper,dishSetmealDishMapper,dishFlavorMapper来操作对应的代码实现其功能
2.调用的方法在对应的接口中没有,我们调用后需要去完善这个方法的功能(增删改查语句)
3.我们使用文字来输出日志时,可以使用自定义的常量来代替,实现更规范的开发,
如:MessageConstant.DISH_ON_SALE=当前菜品在起售中不能删除
4.使用事务注解 @Transactional保证数据的一致性,只要有一个方法删除失败,则整个方法删除都会失败