删除菜品操作

一:需求分析和设计:

  1. 业务规则: 可以一次删除一个菜品,也可以批量删除菜品
  2. 起售中的菜品不能删除
  3. 被套餐关联的菜品不能删除
  4. 删除菜品后,关联的口味数据也需要删除

接口设计:

 

数据库设计 :

 根据以上的业务分析之后,说明我们想删除员工需要对三张表进行操作。

二:具体的代码实现:

Controll层:

    /**
     * 批量删除菜品
     * @param ids
     * @return
     */
    @DeleteMapping
    @ApiOperation("批量删除菜品")
    public Result delete(@RequestParam List<Long> ids){
        log.info("批量删除菜品:{}",ids);
        dishService.deletebatch(ids);
        return Result.success();
    }

在delete这个方法上加了一个@RequestParam注解,这个注解的功能是用于将指定的请求参数赋值给方法中的形参。

在这里加了这个注解之后,SpringMVC框架会自动解析前端传过来的String类型的参数,转化成我们需要的List<Long> ids 这样一个集合。

Service层:

    /**
     * 批量删除菜品
     * @param ids
     * @return
     */
    @Override
    @Transactional
    public void deletebatch(List<Long> ids) {
        //判断当前菜品是否能被删除 -- 是否存在起售中的商品
        for (Long id : ids) {
            Dish dish = dishMapper.selectById(id);
            if(dish.getStatus() == StatusConstant.ENABLE) {//菜品在起售
                throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
            }

        }
        //判断当前菜品是否能够删除 -- 是否被套餐关联了(在套餐表中能查到)
        List<Long> setmealIdsByDishIds = setmealDishMapper.getSetmealIdsByDishIds(ids);
        if(!setmealIdsByDishIds.isEmpty()){
            throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
        }
        //删除菜品表中的菜品数据
        for (Long id : ids) {
            dishMapper.deleteById(id);
            //删除菜品关联的口味数据
            dishFlavorMapper.deleteById(id);
        }
    }

 这个Service层做了4件事。

1:判断这个菜品是否在起售(根据我们的要求,起售是不允许删除的)

判断这个菜品是否在起售,我们就根据这个菜品的id来查询,返回值肯定是一个Dish,所以我们整体的思路就是在dishMapper中写一个selectById的方法,然后在Service层获取这个selectById方法的返回值,并且获取状态。

dishMapper层代码:
    /**
     * 根据菜品id查询菜品
     * @param id
     */
    @Select("SELECT * from sky_take_out.dish where id = #{id}")
    Dish selectById(Long id);

2:判断这个菜品是否被套餐所关联了(关联了我们也不能删除)

首先分析一下这个需求,我们如何知道菜品是否被套餐关联?

根据我们上面数据库设计那个模块,我们知道,我们需要一个中间表setmeal_dish,我们需要在这张表中查询。

所以,我们现在思路是:

创建一个SetmealDishMapper,然后里面有根据菜品id查询对应的套餐的方法。

SetmealMapper层:
@Mapper
public interface SetmealDishMapper {
    /***
     * 根据菜品id查询对应的套餐
     * @param dishIds
     * @return
     */
    List<Long> getSetmealIdsByDishIds(List<Long> dishIds);
}

我们再观察这个查询语句,我们是动态的查询这个dishId,所以这里我们采用动态SQL

 并且利用foreach标签

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

 写到这里,我们就可以对这个结果进行判断了,我们返回的是一个集合

为什么是集合呢,我们这里采用的是批量删除的方式,比如我们选了1,2,3这三个菜品,如果这三个菜品中有任何一个菜品有关联套餐,根据事务的原子性,我们这三个菜品都不能删除。

 我们对这个集合进行一个判空处理就行。

处理条件不满足的情况:

根据上面两个步骤来看,这两个条件中,只要有一个不满足,我们直接就可以结束了,那这个时候,我们怎么来处理或者返回这个异常的信息:抛异常即可

3:前两步都判断之后,第三步可以删除了

到这一步之后,就和常规的删除一样了。

4:删除完这个菜品之后,对应的口味数据也要删除

Mapper层(DishMapper和DishFlavorMapper):

     /**
     * 根据id删除菜品
     * @param id
     */
    @Delete("delete from sky_take_out.dish where id = #{id}")
    void deleteById(Long id);
    /**
     * 根据id删除口味数据
     * @param dishId
     */
    @Delete("delete from sky_take_out.dish_flavor where dish_id = #{dishId}")
    void deleteById(Long dishId);

三:性能优化: 

这个性能优化主要是对:

    //删除菜品表中的菜品数据
        for (Long id : ids) {
            dishMapper.deleteById(id);
            //删除菜品关联的口味数据
            dishFlavorMapper.deleteById(id);
        }

仔细看这一段代码,我们每次遍历一个id的时候,都需要发出两条sql语句,导致性能不高

所以我们的优化思路是将这个遍历的过程方法sql语句中,发送一条sql语句,让一条数据把想要删的数据全删了。

优化后的Service层:

//        //删除菜品表中的菜品数据
//        for (Long id : ids) {
//            dishMapper.deleteById(id);
//            //删除菜品关联的口味数据
//            dishFlavorMapper.deleteById(id);
//        }
        //根据集合id批量删除表中的菜品数据
        dishMapper.deleteIdBatch(ids);
        //根据集合id批量删除相关联的口味数据
        dishFlavorMapper.deleteIdBatch(ids);

DishMapper层及注解: 

    /**
     * 批量删除菜品数据
     * @param ids
     */
    void deleteIdBatch(List<Long> ids);
    <delete id="deleteIdBatch">
        delete from sky_take_out.dish where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>

 DishFlavorMapper层:

    /**
     * 根据id批量删除口味数据
     * @param dishids
     */
    void deleteIdBatch(List<Long> dishids);
<delete id="deleteIdBatch">
        delete from sky_take_out.dish_flavor where id in
        <foreach collection="dishids" item="dishid" close=")" open="(" separator=",">
            #{dishid}
        </foreach>
    </delete>

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值