需求分析和设计
**业务规则:**
-可以一次删除一个菜品,也可以批量删除菜品
-起售中的菜品不能删除
-被套餐关联的菜品不能删除
-删除菜品后,关联的口味数据也需要删除掉
设定一个接口。删除一个也包含在批量删除里面
在判断是否为套餐中的菜品,这里设计了一个数据库表,里面有setmealId和dishId
将套餐和菜品关联起来的表,比如说查询菜品dish通过这个dishId查询表能够查到套餐setMealId那就说明是存在关联就不能删除
DishController
```plaintext
@DeleteMapping
@ApiOperation("菜品批量删除")
public Result delete(@RequestParam List<Long> ids){
//SpringMvc解析字符串ids然后分隔的元素封装进为List数组
//RequestParam注解就可以动态解析字符串,并且id都提取出来封装到List集合
log.info("菜品批量删除{}",ids);
dishService.deleteBatch(ids);
return Result.success();
}
```
DishService
```plaintext
void deleteBatch(List<Long> ids);
```
DishServiceimpl
这里注意给方法加了事务注解,因为里面包括条件限制。主要是删除菜品还要删除口味,故事务原子性原则保证删除一步到位
首先条件是,去便利传进来的ids确定DishId对应的菜品是否正在起售
齐次是,条件是否是套餐中的菜品,是也不能删除。映射方法mapper映射层的SetMealDishMapper去调用查询方法去获得这个
返回值是套餐SetMealId的集合,传进去的参数是DishIds菜品id集合 返回值List不为空并且size>0则说明关联着,就抛出删除异常终止方法
最后删除菜品,删除口味。循环遍历DishIds
```plaintext
@Transactional
public void deleteBatch(List<Long> ids) {
//判断菜品是否可以删除,起售中就不可以删除
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);
}
//删除表中菜品
for (Long id : ids){
dishMapper.deleteById(id);
//删除菜品关联的口味数据
dishFlavorMapper.deleteByDishId(id);
}
}
```
SetMealDishMapper
```plaintext
@Mapper
public interface SetMealDishMapper {
//根据菜品id查询多个套餐id
List<Long> getSetMealIdsByDishIds(List<Long> dishIds);
}
```
SetMealDishMapper
```plaintext
<?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" separator="," open="(" close=")">
#{dishId}
</foreach>
</select>
</mapper>
```
DishMapper
```plaintext
@Delete("delete from dish where id = #{id}")
void deleteById(Long id);
```
DishFlavorMapper.java
```
@Delete("delete from dish_flavor where dish_id = #{dishId}")
void deleteByDishId(Long dishId);
```
思考:对于删除菜品删除口味的id循环遍历,遍历次数过多,sql发出数量过多会引发性能问题。
优化Serviceimpl的for改成批量删除
注释掉单条id删除菜品删除口味的for循环
传参进来菜品ids deleteByIds
```plaintext
dishMapper.deleteByIds(ids);
dishFlavorMapper.deleteByDishIds(ids);
```
DishMapper.xml
```plaintext
<delete id="deleteByIds">
delete from dish where id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
```
DishFlavorMapper.xml
```plaintext
<delete id="deleteByDishIds">
delete from dish_flavor where dish_id in
<foreach collection="dishIds" item="dishId" open="(" close=")" separator=",">
#{dishId}
</foreach>
</delete>
```