苍穹外卖-删除菜品(六)

需求分析和设计
业务规则:
-可以一次删除一个菜品,也可以批量删除菜品
-起售中的菜品不能删除
-被套餐关联的菜品不能删除
-删除菜品后,关联的口味数据也需要删除掉

设定一个接口。删除一个也包含在批量删除里面
在判断是否为套餐中的菜品,这里设计了一个数据库表,里面有setmealId和dishId
将套餐和菜品关联起来的表,比如说查询菜品dish通过这个dishId查询表能够查到套餐setMealId那就说明是存在关联就不能删除

DishController


    @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

    void deleteBatch(List<Long> ids);

DishServiceimpl
这里注意给方法加了事务注解,因为里面包括条件限制。主要是删除菜品还要删除口味,故事务原子性原则保证删除一步到位
首先条件是,去便利传进来的ids确定DishId对应的菜品是否正在起售
齐次是,条件是否是套餐中的菜品,是也不能删除。映射方法mapper映射层的SetMealDishMapper去调用查询方法去获得这个
返回值是套餐SetMealId的集合,传进去的参数是DishIds菜品id集合 返回值List不为空并且size>0则说明关联着,就抛出删除异常终止方法
最后删除菜品,删除口味。循环遍历DishIds


    @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


@Mapper
public interface SetMealDishMapper {


    //根据菜品id查询多个套餐id
    List<Long> getSetMealIdsByDishIds(List<Long> dishIds);

}

SetMealDishMapper

<?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


    @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


        dishMapper.deleteByIds(ids);
        dishFlavorMapper.deleteByDishIds(ids);

DishMapper.xml

 <delete id="deleteByIds">
        delete from dish where id in 
            <foreach collection="ids" item="id" open="(" close=")" separator=",">
                #{id}
            </foreach>

    </delete>

DishFlavorMapper.xml

    <delete id="deleteByDishIds">
        delete from dish_flavor where dish_id in
            <foreach collection="dishIds" item="dishId" open="(" close=")" separator=",">
                #{dishId}
            </foreach>
    </delete>
posted @ 2024-02-25 15:24  launch  阅读(149)  评论(0)    收藏  举报