苍穹外卖Day04套餐管理部分总结

news2024/12/27 14:29:35

写给像我一样完完全全的小白的。本人代码水平一塌糊涂,前几天就是机械地跟着视频敲代码。对于Day04的作业本来感觉代码抓瞎一点不会写,尽力去理解业务逻辑后发现好像也没那么难,整体代码可以仿照Day03新增菜品来进行实现!

一、功能一——新增套餐

1. 根据类型type查询分类

目的是根据category表中的type字段来查询当前选择区对应的是“套餐分类”还是“菜品分类”。这个功能在之前已经完成了。但我还是把代码贴过来看下。

(1)代码实现

1) CategoryContorller
    /**
     * 根据类型查询分类
     * @param type
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("根据类型查询分类")
    public Result<List<Category>> list(Integer type){
        List<Category> list = categoryService.list(type);
        return Result.success(list);
    }

接下来去CategoryService中声明list方法

2)CategoryService
/**
     * 根据类型查询分类
     * @param type
     * @return
     */
    List<Category> list(Integer type);

接下来去CateServiceImpl中实现这个方法

3)CategoryServiceImpl
/**
     * 根据类型查询分类
     * @param type
     * @return
     */
    public List<Category> list(Integer type) {
        return categoryMapper.list(type);
    }

接下来去CategoryMapper中声明list方法,因为需要动态添加status=1的额外条件来进行查询,所以把具体的实现语句放在CategoryMapper.xml文件中来实现

4)CategoryMapper
    /**
     * 根据类型查询分类
     * @param type
     * @return
     */
    List<Category> list(Integer type);
5)CategoryMapper.xml
<select id="list" resultType="Category">
        select * from category
        where status = 1
        <if test="type != null">
            and type = #{type}
        </if>
        order by sort asc,create_time desc
    </select>

到这里就完成了根据type返回分类的操作啦!

2. 根据分类id查询对应哪些菜品,返回菜品列表List<Dish>

(1)思路梳理

刚刚我们通过type获得了分类,接下来就要根据获得的分类来查询菜品啦。“根据分类id查询该分类下对应了哪些菜品”这个接口实现下图的功能2。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/0e73e0c61beb4be4b5bf1fea8cbd65f7.png
现在我们有了分类列表category、也有了菜品列表dish,即将完善的是套餐列表setmeal套餐对应的菜品列表setmeal_dish

分类列表category如下图所示:
在这里插入图片描述
分类列表的type列描述了分类的类型,其中1表示菜品分类,2表示套餐分类。只有type=2的分类id会出现在setmeal表中。setmeal表的具体内容如下图所示:
在这里插入图片描述
dish表中对应的category_id是这道菜所归属的菜品分类的id,它不包含13和15的,因为13和15是category中标志着“套餐分类”的id。dish表的内容如下图所示。
在这里插入图片描述
根据黑马资料里给出的数据库设计文档(如下图所示),setmeal_dish表整合了setmeal表对应的id、dish表对应的id,用来表示“A套餐(通过setmeal_id来标记)由归属于C菜品、D菜品和E菜品等组成(C、D、E等菜品分别有自己的dish_id,而dish表中又有它们分别对应的category_id)”。
在这里插入图片描述

(2)代码实现

1)DishController

返回类型是一个列表,通过category_id查询当前类别中有哪些菜品。所以category_id做参数。

/**
     * 根据分类id查询菜品
     * @param categoryId
     * @return
*/
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result<List<Dish>> list(Long categoryId){
    List<Dish> list = dishService.list(categoryId);
    return Result.success(list);
}
2)DishService

在DishService.java的接口类中记录list方法

/**
     * 根据分类id查询菜品
     * @param categoryId
     * @return
*/
List<Dish> list(Long categoryId);
3)DishServiceImpl

在实现类中,具体地实现list方法,能够根据分类id查询到菜品,并且以列表的形式返回。这里创建了一个 Dish 对象,使用了建造者模式(Builder Pattern)来构建对象。①categoryId(categoryId) 设置了菜品对象的分类ID属性为传入的 categoryId 参数;②status(StatusConstant.ENABLE) 设置了菜品对象的状态为启用状态,这里使用了一个常量 StatusConstant.ENABLE 来表示启用状态;③build() 方法用于构建 Dish 对象。

/**
     * 根据分类id查询菜品
     * @param categoryId
     * @return
*/
public List<Dish> list(Long categoryId) {
    Dish dish = Dish.builder()
        .categoryId(categoryId)
        .status(StatusConstant.ENABLE)
        .build();
    return dishMapper.list(dish);
}

接下来我们还需要在DishMapper中声明**“根据传入的动态dish信息,将查询到的菜品以列表形式返回”**的方法,并在DishMapper.xml中具体实现这一功能。

4)DishMapper
/**
     * 动态条件查询菜品
     * @param dish
     * @return
*/
List<Dish> list(Dish dish);
5)DishMapper.xml

对传入的name、category_id、status分别做判断

<select id="list" resultType="Dish" parameterType="Dish">
    select * from dish
    <where>
        <if test="name != null">
            and name like concat('%',#{name},'%')
        </if>
        <if test="categoryId != null">
            and category_id = #{categoryId}
        </if>
        <if test="status != null">
            and status = #{status}
        </if>
    </where>
    order by create_time desc
</select>

到这里,根据分类id查询菜品的功能就已经完成了!

(3)图片上传功能

在Day03已经实现了。

3. 新增套餐setmeal

这个功能完全可以仿照Day03的新增菜品来进行实现

1) SetmealContorller
/**
 * 套餐管理
 */
@RestController
@RequestMapping("/admin/setmeal")
@Api(tags = "套餐相关接口")
@Slf4j
public class SetmealController {

    @Autowired
    private SetmealService setmealService;

    /**
     * 新增套餐
     * @param setmealDTO
     * @return
     */
    @PostMapping
    @ApiOperation("新增套餐")
    public Result save(@RequestBody SetmealDTO setmealDTO) {
        setmealService.saveWithDish(setmealDTO);
        return Result.success();
    }
}
2) SetmealService
public interface SetmealService {

    /**
     * 新增套餐,同时需要保存套餐和菜品的关联关系
     * @param setmealDTO
     */
    void saveWithDish(SetmealDTO setmealDTO);
}
3) SetmealServiceImpl
/**
 * 套餐业务实现
 */
@Service
@Slf4j
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private SetmealDishMapper setmealDishMapper;
    @Autowired
    private DishMapper dishMapper;

    /**
     * 新增套餐,同时需要保存套餐和菜品的关联关系
     * @param setmealDTO
     */
    @Transactional
    public void saveWithDish(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);

        //向套餐表插入数据
        setmealMapper.insert(setmeal);

        //获取生成的套餐id
        Long setmealId = setmeal.getId();

        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        setmealDishes.forEach(setmealDish -> {
            setmealDish.setSetmealId(setmealId);
        });

        //保存套餐和菜品的关联关系
        setmealDishMapper.insertBatch(setmealDishes);
    }
}

接下来需要再setmeal表中插入套餐数据,还要在setmea_dish表中插入套餐与菜品的关联数据。我们首先来看setmeal表中插入套餐数据的实现

4)SetmealMapper和SetmealMapper.xml
/**
     * 新增套餐
     * @param setmeal
     */
    @AutoFill(OperationType.INSERT)
    void insert(Setmeal setmeal);

有较多动态参数的传入,我们去SetmealMapper.xml中去进行实现

    <insert id="insert" parameterType="Setmeal" useGeneratedKeys="true" keyProperty="id">
        insert into setmeal(category_id, name, price, status, description, image, create_time, update_time, create_user, update_user)
        values (#{categoryId}, #{name}, #{price}, #{status}, #{description}, #{image}, #{createTime}, #{updateTime},
                #{createUser}, #{updateUser})
    </insert>

5)SetmeaDishMapper和SetmeaDishMapper.xml

为了向setmeal_dish表中插入当前套餐对应的所有菜品。

/*
    * 批量保存菜品和套餐的关联关系
    * @param setmealDishes
    * */
    void insertBatch(List<SetmealDish> setmealDishes);

以及SetmeaDishMapper.xml内容的实现

<insert id="insertBatch" parameterType="list">
        insert into setmeal_dish
        (setmeal_id,dish_id,name,price,copies)
        values
        <foreach collection="setmealDishes" item="sd" separator=",">
            (#{sd.setmealId},#{sd.dishId},#{sd.name},#{sd.price},#{sd.copies})
        </foreach>
    </insert>

新增菜品功能大功告成!

二、 套餐管理功能——分页查询

这段也是仿照菜品分页查询来进行实现的,具体的实现代码黑马的文档里已经很清楚了,复制粘贴好累,就不贴啦~
分页查询的功能测试我是通过接口文档来进行的,大概是下面这个样子
在这里插入图片描述

三. 删除套餐

和删除菜品是一样的!先判断当前id的套餐是否处于起售状态,起售状态的套餐是不能被删除的。但是删除菜品时需要判断菜品是否被套餐关联了,删除套餐就不用这个判断了,更简单了一点点。

(1)代码实现

SetmealController和SetmealService就不说了,
下面这段代码是SetmealServiceImpl中关于删除套餐的具体实现
在这里插入图片描述
所以我们需要在setmealMapper中完成getById和deleteById方法
在setmealDishMapper中完成deleteBySetmeal方法

1)setmealMapper

在这里插入图片描述

2)setmealDishMapper

在这里插入图片描述
这个功能通过前后端联调测试一下,以上代码是没有问题的

四、修改套餐

还是仿照修改菜品的那个

1. 根据套餐id查询套餐及对应菜品的信息

(1)代码实现

1)SetmealController

在这里插入图片描述
接下来去声明SetmealService中的getByIdWithDish方法

2)SetmealService

在这里插入图片描述

3) 实现类

在这里插入图片描述
接下来该去SetmealDishMapper里实现getBySetmealId的方法

4)SetmealDishMapper

在这里插入图片描述

2. 修改套餐内容

(1)代码实现

1) SetmealController

在这里插入图片描述

2) SetmealService

在这里插入图片描述

3) 实现类

在这里插入图片描述

4) SetmealMapper和对应的.xml文件

黑马的文档里怎么没有SetmealMapper里的那段啊!!!

因为这个报错调了好久!
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=C%3A%2FUsers%2Flenovo%2FAppData%2FRoaming%2FTypora%2Ftypora-user-images%2Fimage-20240404224412630.png&pos_id=img-oZ3v69vU-1712241928954

以及

<update id="update">
        update setmeal
        <set>
            <if test="categoryId!=null">
                category_id=#{categoryId},
            </if>
            <if test="name!=null">
                name=#{name},
            </if>
            <if test="price!=null">
                price=#{price},
            </if>
            <if test="status!=null">
                status=#{status},
            </if>
            <if test="description!=null">
                description=#{description},
            </if>
            <if test="image!=null">
                image=#{image},
            </if>
            <if test="createTime!=null">
                create_time=#{createTime},
            </if>
            <if test="updateTime!=null">
                update_time=#{updateTime},
            </if>
            <if test="createUser!=null">
                create_user=#{createUser},
            </if>
            <if test="updateTime!=null">
                update_time=#{updateTime}
            </if>
        </set>
    </update>
5)最后还有一个SetmealDishMapper
	/**
     * 根据套餐id查询套餐和菜品的关联关系
     * @param setmealId
     * @return
     */
    @Select("select * from setmeal_dish where setmeal_id = #{setmealId}")
    List<SetmealDish> getBySetmealId(Long setmealId);

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

scratch寻找好朋友 2024年3月中国电子学会 图形化编程 scratch编程等级考试二级真题和答案解析

目录 scratch寻找好朋友 一、题目要求 1、准备工作 2、功能实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、…

如何在Linux中安装软件

文章目录 一、Linux应用程序基础1.Linux软件安装包分类2.应用程序和系统命令的关系3.常见的软件包的封装类型 二、安装软件的方式1.RPM包管理工具2.yum安装3.编译 一、Linux应用程序基础 1.Linux软件安装包分类 Linux源码包&#xff1a; 实际上&#xff0c;源码包就是一大堆源…

Spring/SpringBoot/SpringCloud Mybatis 执行流程

在后续分析Mybatis 流程中代码的可能会用到IDEA debug 技巧&#xff1a; 条件断点 代码断点&#xff0c;右键 勾选弹窗 Condition &#xff1a; 写入表达式 回到上一步&#xff1a; Java动态代理实现 InvocationHandler接口&#xff1a; package com.lvyuanj.core.test;…

MAX7219驱动数码管学习记录(有源码)

一、7219datasheet阅读 1.引脚定义&#xff1a; 重点介绍5个引脚 1.DIN&#xff1a; 串行数据总线输入引脚&#xff0c;每个时钟的上升沿将数据移入至芯片内部的移位寄存器中 2.DIG0-DIG7: 共阴极管的GND连接的便是DIG0-7,该引脚起作用时&#xff0c;便输出低电平&#xff0c…

SSM学习——Spring JDBC

Spring JDBC 概念 Spring的JDBC模块负责数据库资源管理和错误处理&#xff0c;简化了开发人员对数据库的操作。 Spring JDBC通过配置数据源和JDBC模板来配置。 针对数据库操作&#xff0c;Spring框架提供了JdbcTemplate类&#xff0c;它是Spring框架数据抽象层的基础&#…

【学习】渗透测试有哪些重要性

随着信息技术的迅猛发展&#xff0c;网络安全问题日益凸显。渗透测试作为网络安全防御的重要手段之一&#xff0c;旨在模拟黑客攻击&#xff0c;发现并修复潜在的安全漏洞&#xff0c;提高网络系统的安全性。本文将介绍渗透测试的概念、重要性、实施步骤及实践案例&#xff0c;…

echarts快速入门

文章目录 一、echarts下载1.1、下载说明1.2、使用说明 二、绘制一个简单图表 一、echarts下载 echarts是百度研发团队开发的一款报表视图JS插件&#xff0c;功能十分强大&#xff0c;可在echart官网下载源码&#xff08;一个echarts.min.js文件&#xff09;进行使用。 1.1、…

Star GAN论文解析

论文地址&#xff1a;https://arxiv.org/pdf/1912.01865v1.pdf https://openaccess.thecvf.com/content_cvpr_2018/papers/Choi_StarGAN_Unified_Generative_CVPR_2018_paper.pdf 源码&#xff1a;stargan项目实战及源码解读-CSDN博客 1. 概述 在传统方法中&#x…

R语言技能 | 不同数据类型的转换

原文链接&#xff1a;R语言技能 | 不同数据类型的转换 本期教程 写在前面 今天是4月份的第一天&#xff0c;再过2天后再一次迎来清明小假期。木鸡大家是否正常放假呢&#xff1f; 我们在使用R语言做数据分析时&#xff0c;会一直对数据进行不同类型的转换&#xff0c;有时候…

揭秘视觉Transformer之谜,TokenTM新法,全面提升模型解释性能

引言&#xff1a;揭示视觉Transformer的解释挑战 在计算机视觉应用中&#xff0c;Transformer模型的流行度迅速上升&#xff0c;但对其内部机制的后置解释仍然是一个未探索的领域。视觉Transformers通过将图像区域表示为转换后的tokens&#xff0c;并通过注意力权重将它们整合起…

一篇文章带你掌握二叉树(附带二叉树基本操作完整代码演示,和两种思路)

【本长内容】 1. 掌握树的基本概念 2. 掌握二叉树概念及特性 3. 掌握二叉树的基本操作 4. 完成二叉树相关的面试题练习 1. 树形结构 1.1 概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是…

RK3568平台 Uart驱动框架

一.TTY子系统 在Linux kernel中&#xff0c;tty驱动不像于spi&#xff0c;iic等那么架构简单&#xff0c;它是一个庞大的系统&#xff0c;它的框架大体如下图一。我们作为普通的驱动开发移植人员&#xff0c;不会从零写tty驱动&#xff0c;一般都是厂家根据现有的tty驱动和自家…

SpringBoot整合MyBatis四种常用的分页方式

目录 方式1 一、准备工作 1. 创建表结构 2. 导入表数据 3. 导入pom.xml依赖 4. 配置application.yml文件 5. 创建公用的实体类 项目结构 2. 创建controller层 3. 创建service层 4. 创建mapper层 5. 创建xml文件 6. 使用postman进行测试&#xff0c;测试结果如下…

基于JAVA+SpringBoot+Vue的前后端分离的大学健康档案管理系统

一、项目背景介绍&#xff1a; 随着社会的发展和科技的进步&#xff0c;人们越来越重视健康问题。大学作为培养人才的摇篮&#xff0c;学生的健康状况直接影响到国家的未来。然而&#xff0c;传统的大学健康档案管理方式存在诸多问题&#xff0c;如信息不透明、数据分散、更新不…

从零开始为香橙派orangepi zero 3移植主线linux——2.kernel + rootfs

从零开始为香橙派orangepi zero 3移植主线linux——2.kernel rootfs 参考文章&#xff1a;一、linux kernel移植二、根文件系统2.1 buildroot构建1.修改toolchain下的交叉编译链2.修改系统配置3.去除内置kernel和uboot编译4.添加rootfs.tar格式的输出 2.2 ubuntu-base移植 三、…

WebAuthn:更好地保护线上敏感信息

1. 引言 2023年知乎博客 WebAuthn: 真正的无密码身份认证 总结得很赞。 在数字时代&#xff0c;密码已成为人们日常生活和在线活动中不可或缺的一部分。尽管互联网已经发展了 20 多年&#xff0c;许多方面都有了巨大的改进&#xff0c;但只有密码&#xff0c;还是 20 年前的用…

【数据结构】--- 探索栈和队列的奥秘

关注小庄 顿顿解馋૮(˶ᵔ ᵕ ᵔ˶)ა &#x1f4a1;个人主页&#xff1a;9ilk &#x1f4a1;专栏&#xff1a;数据结构之旅 上回我们学习了顺序表和链表&#xff0c;今天博主来讲解两个新的数据结构 — 栈和队列 &#xff0c; 请放心食用 文章目录 &#x1f3e0; 栈&#x1…

牛客 2024春招冲刺题单 ONT102 牛牛的果实排序【simpe 要知道如何判断是否是质数 Java,Go,PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/975a263e2ae34a669354e0bd64db9e2a 核心 需要牢牢记住下面的代码//判断是否为质数public boolean isPrime(int n){if(n1) return false;if(n2 || n3) return true;if(n%6!1 && n%6!5) return false; /…

C++(语法以及易错点2)

1.内联函数 1.1 概念 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内联函数的地方展开&#xff0c;没有函数调 用建立栈帧的开销&#xff0c;内联函数提升程序运行的效率。 ​int ADD(int a,int b) {return ab; }​ 1.2 特性 1. inline是一种以空间换时间…

spring security6重写登陆验证

spring security的认证流程 2. 从文档上可以看出来&#xff0c;UsernamePasswordAuthenticationFilter和AuthenticationManager是认证的关键步骤&#xff0c;/login传过来的username和password由UsernamePasswordAuthenticationFilter接收处理成UsernamePasswordAuthenticatio…