当前位置: 首页 > news >正文

修改菜品-02.代码开发

一.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();
    }

    /**
     * 根据id查询菜品
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @ApiOperation("根据id查询菜品")
    public Result<DishVO> getById(@PathVariable Long id) {
        log.info("根据id查询菜品:{}",id);
        DishVO dishVO = dishService.getByIdWithFlavor(id);
        return Result.success(dishVO);
    }

    /**
     * 修改菜品
     * @param dishDTO
     * @return
     */
    @PutMapping()
    @ApiOperation("修改菜品")
    public Result update(@RequestBody DishDTO dishDTO) {
        log.info("修改菜品:{}",dishDTO);
        dishService.updateWithFlavor(dishDTO);
        return Result.success();
    }
}

使用DishDTO进行前端数据的接收,因为我们要使用Json格式封装前端数据,因此我们使用@RequestBody注解修饰。我们之所以要使用DishDTO对象进行数据接收,是因为DishDTO中含有口味列表数据,可以对修改的口味进行封装传递到后台服务器数据库中。 

二.Service层

接口

package com.sky.service;

import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.result.PageResult;
import com.sky.vo.DishVO;
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);

    /**
     * 根据id查询菜品
     * @param id
     * @return
     */
    DishVO getByIdWithFlavor(Long id);

    /**
     * 修改菜品
     * @param dishDTO
     */
    void updateWithFlavor(DishDTO dishDTO);
}

实现类 

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      // 要对dish表和dish_flavor表同时进行操作,因此要使用事务,这两个操作要么同时成功,要么同时失败
    @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);  // 批量删除口味
    }

    /**
     * 根据id查询菜品
     * @param id
     * @return
     */
    @Override
    @Transactional
    public DishVO getByIdWithFlavor(Long id) {
        Dish dish = dishMapper.getById(id);
        List<DishFlavor> dishFlavors = dishFlavorMapper.getByDishId(id);

        DishVO dishVO = new DishVO();
        BeanUtils.copyProperties(dish,dishVO);
//        BeanUtils.copyProperties(dishFlavors,dishVO);   不能使用BeanUtils的copyProperties方法拷贝集合对象
//        这里不用管DishVO中的categoryName属性拿不到值,因为前端已经封装好了该id对应的categoryName
        dishVO.setFlavors(dishFlavors);

        return dishVO;
    }

    /**
     * 修改菜品
     * @param dishDTO
     */
    @Transactional
    @Override
    public void updateWithFlavor(DishDTO dishDTO) {
        // 1.首先修改菜品数据
        Dish dish = new Dish(); // 将Dish实体类对象写入数据表中
        BeanUtils.copyProperties(dishDTO,dish);
        dishMapper.update(dish);

        // 2.接着修改菜品关联的口味数据。在修改口味数据时,因为有多种可能,可能不变,可能全变,可能部分变,因此我们采用将当前菜品关联口味删除再重新添加到数据库中的方法
        // 先删除
        dishFlavorMapper.deleteByDishId(dishDTO.getId());
        // 再插入
        List<DishFlavor> dishFlavors = dishDTO.getFlavors();
        if (dishFlavors != null && dishFlavors.size() > 0) {    // 有数据再插入,没数据不插入
            for (DishFlavor flavor : dishFlavors) {
                flavor.setDishId(dishDTO.getId());
            }
            // 向口味表插入n条数据
            dishFlavorMapper.insertBatch(dishFlavors);
        }
    }
}

在实现类中我们首先修改菜品数据,因为要想dish表中修改数据,因此我们使用Dish实体类对象进行接收,并调用mapper层的update方法进行数据修改。 我们将dishDTO中的属性进行属性拷贝到dish对象中。

接着修改菜品关联的口味数据。在修改口味数据时,因为有多种可能,可能不变,可能全变,可能部分变,因此我们采用将当前菜品关联口味删除再重新添加到数据库中的方法。首先调用deleteByDishId删除该id对应口味,然后再判断是否从前端获取到了口味列表,如果该列表不为空且有值,就遍历该列表并对flavor对象的dishId属性赋值,然后将这些口味数据插入即可。没有就不执行批量插入insertBatch()操作。

三.Mapper层

DishMapper接口

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);

    /**
     * 修改菜品
     * @param dish
     */
    @AutoFill(value = OperationType.UPDATE)
    void update(Dish dish);
}

DishFlavorMapper接口 

package com.sky.mapper;

import com.sky.entity.DishFlavor;
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 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);

    /**
     * 根据菜品id批量查询对应口味
     * @param dishId
     */
    @Select("select * from dish_flavor where dish_id = #{dishId}")
    List<DishFlavor> getByDishId(Long dishId);
}

DishMapper接口 

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

    <update id="update">
        update dish
        <set>
            <if test="name != null and name != ''">
                name = #{name},
            </if>
            <if test="categoryId != null">
                category_Id = #{categoryId},
            </if>
            <if test="price != null">
                price = #{price},
            </if>
            <if test="image != null and image != ''">
                image = #{image},
            </if>
            <if test="description != null and description != ''">
                description = #{description},
            </if>
            <if test="status != null">
                status = #{status},
            </if>
            <if test="updateTime != null">
                update_time = #{updateTime},
            </if>
            <if test="updateUser != null">
                update_user = #{updateUser},
            </if>
        </set>
        where id = #{id}
    </update>
</mapper>

 DishFlavorMapper接口

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

功能测试

查询

修改 

修改成功 

相关文章:

  • Copilot完全指南:AI编程助手的革命性实践
  • WEB或移动端常用交互元素及组件 | Axure / 元件类型介绍(表单元件、菜单和表格 、流程元件、标记元件)
  • 口腔种植全流程AI导航系统及辅助诊疗与耗材智能化编程分析
  • TDengine 中的命名与边界
  • Go 语言标准库中time模块详细功能介绍与示例
  • 自动化发布工具CI/CD实践Jenkins部署与配置教程
  • 网络空间安全(43)Linux实战篇
  • 深度解析衡石科技HENGSHI SENSE嵌入式分析能力:如何实现3天快速集成
  • vue状态管理器pinia、pinia-plugin-persist持久化储存
  • 鸿蒙Next-集成HmRouter的路由模式
  • Vala编程语言教程-属性
  • 鸿蒙OS 5.0 服务能力框架深入剖析
  • 手机零售行业的 AI 破局与创新降本实践 | OceanBase DB大咖说
  • 《第三次世界大战》第一章:战争的前夜
  • Java StringUtils工具类常用方法详解
  • COMPASS:通过残差强化学习和技能合成实现跨具身移动策略
  • 深入解剖Linux进程:从诞生到调度的核心机制
  • 2.1-WAF\CDN\OSS\反向代理\负载均衡
  • linux 硬盘扩展
  • PHP弱类型全面复盘
  • 哔哩哔哩推广网站/企业微信营销管理软件
  • 重庆南川网站制作公司推荐/网络推广公司口碑
  • 中山建站/官网整站优化
  • 如何自己做软件网站/营销方案怎么写?
  • 宁波seo服务推广平台/山东网络优化公司排名
  • 网站底色什么颜色好看/快速整站优化