删除菜品-02.代码实现

一.删除菜品

在前面我们分析了删除菜品的业务逻辑,其中前端传递过来的参数是一个字符串类型的参数。比如要删除id为1,2,3的菜品,那么前端传递过来的参数就是?1,2,3。这种参数类型如果接收的话我们应该使用@RequestParam,因为我们要将其传递过来的参数封装到一个List集合当中,因此我们使用@RequestParam。这样Spring MVC 会映射以逗号分割的参数,然后将其填入List集合中。

此外,在删除菜品时也要注意,以下情况是必须要考虑的。

二.Controller层

package com.sky.controller.admin;

import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/admin/dish")
@Api(tags = "菜品相关接口")
@Slf4j
public class DishController {
    @Autowired
    private DishService dishService;


    /**
     * 新增菜品
     * @param dishDTO
     * @return
     */
    @PostMapping
    @ApiOperation("新增菜品")
    public Result save(@RequestBody DishDTO dishDTO) {  // 前端传递过来的Json格式的数据,要使用@RequestBody注解修饰变量来接收
        log.info("新增菜品:{}",dishDTO);
        dishService.saveWithFlavor(dishDTO);
        return Result.success();
    }

    /**
     * 菜品分页查询
     * @param dishPageQueryDTO
     * @return
     */
    @GetMapping("/page")
    @ApiOperation("菜品分页查询")
    public Result<PageResult> page(DishPageQueryDTO dishPageQueryDTO) {
        log.info("菜品分页查询:{}",dishPageQueryDTO);
        PageResult pageResult = dishService.pageQuery(dishPageQueryDTO);
        return Result.success(pageResult);
    }

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

 三.Service层

接口

package com.sky.service;

import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.result.PageResult;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public interface DishService {

    /**
     * 新增菜品
     * @param dishDTO
     */
    void saveWithFlavor(DishDTO dishDTO);

    /**
     * 菜品分页查询
     * @param dishPageQueryDTO
     * @return
     */
    PageResult pageQuery(DishPageQueryDTO dishPageQueryDTO);

    /**
     * 批量删除菜品
     * @param ids
     */
    void deleteByIds(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 org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.function.Consumer;

@Service
public class DishServiceImpl implements DishService {
    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private DishFlavorMapper dishFlavorMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;
    /**
     * 新增菜品
     * @param dishDTO
     */
    @Transactional  // 要对dish表和dish_flavor表同时进行操作,因此要使用事务,这两个操作要么同时成功,要么同时失败
    @Override
    public void saveWithFlavor(DishDTO dishDTO) {
        // 我们要往dish表里写入数据,因此要创建一个Dish对象,将该Dish对象插入表中
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO,dish);
        // 向dish表插入1条数据
        dishMapper.insert(dish);

        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (flavors != null && flavors.size() > 0) {
            // 注意:我们在dish_flavor往里插入数据的时候,需要拿到当前dish的id,才能插入到dish_flavor中的dishId字段
            Long dishId = dish.getId();     // 直接这样获取是获取不到的,因为默认情况下,执行基础的insert操作,是不会把主键值返回的。即使在数据库中已为其分配了主键id,但是直接get是无法拿到的,这时候就要使用主键返回功能 https://www.bilibili.com/video/BV1m84y1w7Tb?spm_id_from=333.788.videopod.episodes&vd_source=29b615752ffbc51f0ac76a344682247a&p=126
            flavors.forEach(dishFlavor -> {
                dishFlavor.setDishId(dishId);   // lambda表达式,遍历flavor集合并为其中的dishId属性赋值
            });
            // 向口味表插入n条数据
            dishFlavorMapper.insertBatch(flavors);  // 批量插入
        }
    }

    /**
     * 菜品分页查询
     * @param dishPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(DishPageQueryDTO dishPageQueryDTO) {
        // 执行PageHelper插件
        PageHelper.startPage(dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize());
        // 执行Mapper层进行查询
        Page<DishVO> page =  dishMapper.pageQuery(dishPageQueryDTO);
        return new PageResult(page.getTotal(),page.getResult());
    }

    /**
     * 批量删除菜品
     * @param ids
     */
    @Transactional
    @Override
    public void deleteByIds(List<Long> ids) {
        // 1.首先判断该菜品状态,有启售售状态菜品则该次删除操作失败
        for (Long id : ids) {
            Dish dish = dishMapper.getById(id);  // 根据id查询对应菜品
            Integer status = dish.getStatus();
            if (status == StatusConstant.ENABLE)
                throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
        }

        // 2.接着判断该菜品是否有关联的套餐,有关联套餐的菜品则该次删除操作失败————查询setmeal_dish表
        List<Long> setmealIds = setmealDishMapper.getSetmealIdsByDishIds(ids);
        if (setmealIds != null && setmealIds.size() > 0) {
            throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
        }

//        // 3.批量删除菜品
//        for (Long id : ids) {
//            dishMapper.deleteByIds(id);     // 之所以不用动态批量删除,是因为还要删除dish_id对应的口味,因此直接查一删一方便
//            // 4.删除菜品关联的口味
//            dishFlavorMapper.deleteByDishId(id);
//        }

        // 虽然使用for循环一一删除逻辑上简单,但是使用for循环每次调用两个mapper接口,性能影响大,因此使用批量删除
        dishMapper.deleteByIds(ids);    // 批量删除菜品
        dishFlavorMapper.deleteByDishIds(ids);  // 批量删除口味
    }
}

1.首先判断该菜品状态,有启售售状态菜品则该次删除操作失败。因此要根据id进行菜品的查询并判断菜品status,如果status等于1,那么就抛出菜品启售异常。

2.接着判断该菜品是否有关联的套餐,有关联套餐的菜品则该次删除操作失败————查询setmeal_dish表。我们通过查询该菜品关联的套餐来确定时候该菜品有套餐关联,如果有就不允许删除。因此我们使用SQL语句:

select setmeal_id from setmeal_dish where dish_id in ids; 

使用集合接收查询到的套餐id。如果该集合不为空且该集合中的元素个数大于零,那么就证明这些菜品与套餐有关联,那么就抛出菜品关联套餐异常,不允许删除。

3.如果当前要删除的菜品既没有启售的,又没有与套餐相关联的,那么就允许删除。我们会删菜品以及其关联的口味,因此要操作两个表:dish,dish_flavor表。我们要让这两个表要么同时删除成功,要门同时删除失败,因此在方法上加上@Transactional注解表示该方法下的操作是一个事务。

我们调用deleteByIds(ids)批量删除菜品,调用deleteByDishIds(ids)批量删除口味。

四.Mapper层

DishMapper.class

package com.sky.mapper;

import com.github.pagehelper.Page;
import com.sky.annotation.AutoFill;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.enumeration.OperationType;
import com.sky.vo.DishVO;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface DishMapper {

    /**
     * 根据category_id查询菜品中的该分类数
     * @param categoryId
     * @return
     */
    @Select("select count(*) from dish where category_id = #{categoryId}")
    Integer countByCategoryId(Long categoryId);

    /**
     * 新增菜品
     * @param dish
     */
    @AutoFill(value = OperationType.INSERT)
    void insert(Dish dish);

    /**
     * 菜品分页查询
     * @param dishPageQueryDTO
     * @return
     */
    Page<DishVO> pageQuery(DishPageQueryDTO dishPageQueryDTO);

    /**
     * 根据id查询菜品
     * @param id
     * @return
     */
    @Select("select * from dish where id = #{id}")
    Dish getById(Long id);

    /**
     * 删除菜品
     * @param id
     */
    @Delete("delete from dish where id = #{id}")
    void deleteById(Long id);

    /**
     * 批量删除菜品
     * @param ids
     */
    void deleteByIds(List<Long> ids);
}

 SetmealDishMapper.class

package com.sky.mapper;

import com.sky.entity.SetmealDish;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface SetmealDishMapper {

    /**
     * 根据菜品id查询所在套餐id
     * @param ids
     * @return
     */
    List<Long> getSetmealIdsByDishIds(List<Long> ids);
}

DishFlavorMapper.class 

package com.sky.mapper;

import com.sky.entity.DishFlavor;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface DishFlavorMapper {
    /**
     * 新增口味
     * @param dishFlavors
     */
    void insertBatch(List<DishFlavor> dishFlavors);   // 要进行批量添加,将集合中的元素都添加进去,因此要使用<foreach>


    /**
     * 根据菜品id删除对应口味
     * @param dishId
     */
    @Delete("delete from dish_flavor where dish_id = #{dishId}")
    void deleteByDishId(Long dishId);

    /**
     * 根据菜品id批量删除对应口味
     * @param dishIds
     */
    void deleteByDishIds(List<Long> dishIds);
}

DishMapper.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.DishMapper">
    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into dish(name, category_id, price, image, description, status, create_time, update_time, create_user, update_user)
        VALUES
        (#{name},#{categoryId},#{price},#{image},#{description},#{status},#{createTime},#{updateTime},#{createUser},#{updateUser})
    </insert>
    <delete id="deleteByIds">
        delete from dish where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
    <select id="pageQuery" resultType="com.sky.vo.DishVO">
        select d.*,c.name as categoryName from dish d left outer join category c on d.category_id = c.id
        <where>
            <if test="name != null and name !=''">
                and d.name like concat('%',#{name},'%')
            </if>
            <if test="categoryId != null">
                and d.category_id = #{categoryId}
            </if>
            <if test="status != null">
                and d.status = #{status}
            </if>
        </where>
        order by create_time desc
    </select>
</mapper>

 SetmealDishMapper.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="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </select>
</mapper>

 DishFlavorMapper.class 

<?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.DishFlavorMapper">
    <insert id="insertBatch">
        insert into dish_flavor(dish_id, name, value) VALUES
        <foreach collection="dishFlavors" item="dishFlavor" separator=",">
        (#{dishFlavor.dishId}, #{dishFlavor.name}, #{dishFlavor.value})
        </foreach>
    </insert>
    <delete id="deleteByDishIds">
        delete from dish_flavor where dish_id in
        <foreach collection="dishIds" item="dishId" separator="," open="(" close=")">
            #{dishId}
        </foreach>
    </delete>
</mapper>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值