修改菜品-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 {@Autowiredprivate 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 {@Autowiredprivate DishMapper dishMapper;@Autowiredprivate DishFlavorMapper dishFlavorMapper;@Autowiredprivate SetmealDishMapper setmealDishMapper;/*** 新增菜品* @param dishDTO*/@Transactional  // 要对dish表和dish_flavor表同时进行操作,因此要使用事务,这两个操作要么同时成功,要么同时失败@Overridepublic 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=126flavors.forEach(dishFlavor -> {dishFlavor.setDishId(dishId);   // lambda表达式,遍历flavor集合并为其中的dishId属性赋值});// 向口味表插入n条数据dishFlavorMapper.insertBatch(flavors);  // 批量插入}}/*** 菜品分页查询* @param dishPageQueryDTO* @return*/@Overridepublic 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表同时进行操作,因此要使用事务,这两个操作要么同时成功,要么同时失败@Overridepublic 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@Transactionalpublic 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对应的categoryNamedishVO.setFlavors(dishFlavors);return dishVO;}/*** 修改菜品* @param dishDTO*/@Transactional@Overridepublic 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>

功能测试

查询

修改 

修改成功 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/42629.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探秘Transformer系列之(19)----FlashAttention V2 及升级版本

探秘Transformer系列之&#xff08;19&#xff09;----FlashAttention V2 及升级版本 文章目录 探秘Transformer系列之&#xff08;19&#xff09;----FlashAttention V2 及升级版本0x00 概述0x01 FlashAttention V21.1 动机1.2 方案1.2.1 减少冗余计算1.2.2 增加并行1.2.3 调整…

解决HuggingFaceEmbeddings模型加载报错:缺少sentence-transformers依赖包

遇到报错 报错信息: Error loading model: Could not import sentence_transformers python package. Please install it with pip install sentence-transformers. 装包信息&#xff1a; pip install modelscope langchain sentence_transformers langchain-huggingface on…

外星人入侵(python设计小游戏)

这个游戏简而言之就是操作一个飞机对前方的飞船进行射击&#xff0c;和一款很久之前的游戏很像&#xff0c;这里是超级低配版那个游戏&#xff0c;先来看看效果图&#xff1a; 由于设计的是全屏的&#xff0c;所以电脑不能截图。。。。 下面的就是你操控的飞船&#xff0c;上面…

游戏引擎学习第188天

回顾并计划今天的内容 原本这周的目标是进行可视化操作的尝试&#xff0c;但每一天都被一些棘手的bug和问题所阻碍&#xff0c;导致我们一直没能实现这个目标。直到今天&#xff0c;星期四&#xff0c;我们终于解决了这些问题&#xff0c;所有功能都能正常运行了&#xff0c;所…

解决 FFmpeg 使用 C/C++ 接口时,解码没有 shell 快的问题(使用多线程)

一、问题 硬件设备为香橙派 5Plus&#xff0c;最近需要使用硬件视频解码来加速 YOLO 的检测&#xff0c;shell 窗口的FFmpeg已经调通&#xff0c;详见文章&#xff1a; 编译支持 RKmpp 和 RGA 的 ffmpeg 源码_rk3588 ffmpeg mpp-CSDN博客https://blog.csdn.net/plmm__/article…

玛哈特液压式精密矫平机——以精准压力,定义金属的绝对服从

板材应力不除&#xff0c;良率难升。液压式精密矫平机&#xff0c;凭借多级液压闭环技术AI动态补偿算法&#xff0c;攻克0.2mm超薄钛箔至65mm装甲钢板的矫平极限&#xff0c;平整度精度锁定0.012mm&#xff0c;残余应力≤3MPa&#xff0c;让金属从“形似平整”迈向“分子级稳定…

食品计算—Nutrition5k: Towards Automatic Nutritional Understanding of Generic Food

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

C++11--(1)

目录 1.列表初始化 {}初始化 C98中 C11中 内置置类型和自定义类型 创建对象也适用 std::initializer_list 2.变量类型推导 auto C98 C11 decltype nullptr 3.范围for循环 4.STL中一些变化 array 1.创建和初始化 2.访问元素 ​编辑 3.修改操作 4.支持迭代器…

Tabby 一:如何在Mac配置保姆级教程(本地模型替换hugging face下载)

1. brew安装 mac需要先安装brew&#xff0c;如果本地已经安装过brew这一步可以忽略&#xff0c;遇到问题可以自己ai问 /bin/bash -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 可能遇到source .zprofile失败&#xff0c;因为…

内网服务器无法通过公网地址访问映射到公网的内网服务

内网服务器无法通过公网地址访问映射到公网的内网服务 问题现象问题原因解决方法总结 前几天遇到一个网络问题&#xff0c;在这里做下记录&#xff0c;希望能帮助到有相同问题的朋友。 问题现象 网络拓扑如上所示&#xff0c;服务器1和服务器2在同一内网&#xff0c;网段均为1…

mac 下配置flutter 总是失败,请参考文章重新配置flutter 环境MacOS Flutter环境配置和安装

一、安装和运行Flutter的系统环境要求 想要安装并运行 Flutter&#xff0c;你的开发环境需要最低满足以下要求&#xff1a; 操作系统:macOS磁盘空间:2.8 GB(不包括IDE/tools的磁盘空间)。工具:Flutter使用git进行安装和升级。我们建议安装Xcode&#xff0c;其中包括git&#x…

Linux的进程信号 -- 信号产生,信号保存,信号捕捉,硬件中断,内核态和用户态,可重入函数,volatile,SIGCHLD

目录 1. 认识信号 1.1 信号的定义和基本结论 1.1.1 查看信号 1.2 技术应用角度的信号 1.2.1 一个样例 1.2.2 系统调用 signal 函数 1.3 信号的处理 2. 信号的产生 2.1 通过终端按键产生信号 2.1.1 基本操作 2.1.2 理解操作系统如何得知键盘信号 2.1.3 初步理解信号…

知识库中嵌入模型(Embedding Models)与重排序模型(Re-ranking Models)推荐工具与库

一、引言 在当今信息爆炸的时代&#xff0c;企业和组织面对海量数据时&#xff0c;如何快速、准确地检索和利用知识成为一项关键技术。知识库作为信息管理和知识发现的核心平台&#xff0c;已经广泛应用于搜索引擎、问答系统、智能客服、推荐系统等领域。然而&#xff0c;传统…

C++调用Python

Python安装 地址&#xff1a; python官网 可以根据需要下载对应的版本。 调用python python测试脚本 # my_script.py import sys import jsondef calculate(a, b):return a * b 10 # 示例计算逻辑if __name__ "__main__":# 从命令行参数读取 JSON 字符串try…

Linux 中查看文件大小方法

目录 方法一&#xff1a;ls -l 输出的第五列方法二&#xff1a;du 命令的输出信息方法三&#xff1a;stat -c %s 的输出 方法一&#xff1a;ls -l 输出的第五列 ls 是列出指定目录下文件列表的命令&#xff0c;通过 -l 选项可以显示文件的属性信息&#xff0c;第五列显示的就是…

初识Qt(一)

本文部分ppt、视频截图原链接&#xff1a;萌马工作室的个人空间-萌马工作室个人主页-哔哩哔哩视频 1. Qt是什么&#xff1f; Qt是一个跨平台的C应用程序开发框架&#xff0c;它既为图形用户界面(GUI)程序开发提供了强大支持&#xff0c;也能用于开发非GUI的控制台程序、服务端…

docker - compose up - d`命令解释,重复运行会覆盖原有容器吗

docker - compose up - d`命令解释,重复运行会覆盖原有容器吗 docker - compose up - d 是一个用于管理 Docker 容器的命令,具体含义如下: 命令含义: up:用于创建、启动并运行容器,会根据 docker - compose.yml 文件中定义的服务配置来操作。-d:表示以“分离模式”(det…

《2核2G阿里云神操作!Ubuntu+Ollama低成本部署Deepseek模型实战》

简介&#xff1a; “本文为AI开发者揭秘如何在阿里云2核2G轻量级ECS服务器上&#xff0c;通过Ubuntu系统与Ollama框架实现Deepseek模型的高效部署。无需昂贵硬件&#xff0c;手把手教程涵盖环境配置、资源优化及避坑指南&#xff0c;助力初学者用极低成本在云端跑通行业领先的大…

DexGrasp Anything:具有物理-觉察的普遍机器人灵巧抓取

25年3月来自上海科技大学的论文“DexGrasp Anything: Towards Universal Robotic Dexterous Grasping with Physics Awareness”。 能够抓取任何物体的灵巧手&#xff0c;对于通用具身智能机器人的开发至关重要。然而&#xff0c;由于灵巧手的自由度高&#xff0c;物体种类繁多…

COMPASS:通过残差强化学习和技能合成实现跨具身移动策略

25年2月来自 Nvidia、UC Berkeley 和 UT Austin 的论文“COMPASS: Cross-embOdiment Mobility Policy via ResiduAl RL and Skill Synthesis”。 随着机器人越来越多地部署在不同的应用领域&#xff0c;可泛化的跨具身移动策略变得越来越重要。虽然经典的移动栈已被证明在特定…