• SpringBoot 项目实战 ~ 5.菜品管理



    家住在女贞路 4 号的德思礼夫妇…


    在这里插入图片描述


    一、上传、下载

    1. 接收上传文件

    新建 src/main/java/com/reggie/controller/CommonController 类:

    package com.reggie.controller;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.multipart.MultipartFile;
    
    /**
     * 文件的上传和下载
     */
    @RestController
    @RequestMapping("/common")
    @Slf4j
    public class CommonController {
    
        /**
         * 文件上传
         * @param file
         * @return
         */
        @PostMapping("/upload")
        public R<String> upload(MultipartFile file  ) {
            System.out.println(file);
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25


    2. 文件上传服务端

    编辑 src/main/java/com/reggie/controller/CommonController 类:

    ...
    
    /**
     * 文件的上传和下载
     */
    @RestController
    @RequestMapping("/common")
    @Slf4j
    public class CommonController {
    
        /**
         * 文件上传
         * @param file
         * @return
         */
        @PostMapping("/upload")
        public R<String> upload(MultipartFile file  ) {
            log.info(file.toString());
    
            // 获取原始文件文件名
            String originalFilename = file.getOriginalFilename();
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
    
            // 使用 UUID重新生成文件名,防止文件名称重复造成we文件覆盖
            String fileName = UUID.randomUUID().toString() + suffix;
    
            // 创建一个目录对象
            File dir = new File(basePath);
            // 判断当前目录是否存在
            if(!dir.exists()) {
                // 目录不存在,需要创建
                dir.mkdirs();
            }
    
            // 将临时文件转存到指定路径
            try {
                file.transferTo(new File(basePath + fileName));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
    
            return R.success(fileName);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44


    3. 文件下载

    编辑 src/main/java/com/reggie/controller/CommonController 类:

    ...
    
        /**
         * 文件下载
         * @param name
         * @param response
         */
        @GetMapping("/download")
        public void download(String name, HttpServletResponse response) {
            try {
                // 输入流,读取文件内容
                FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));
    
                // 输出流,通过输出流将文件写回浏览器
                ServletOutputStream outputStream = response.getOutputStream();
    
                response.setContentType("image/jpeg");
    
                int len = 0;
                byte[] bytes = new byte[1024];
                while ((len = fileInputStream.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, len);
                    outputStream.flush();
                }
    
                // 关闭资源
                fileInputStream.close();
                outputStream.close();
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36


    4. 测试文件(前端)

    新建 src/main/resources/backend/page/demo/upload.html 测试页面:

    DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>文件上传title>
      
      <link rel="stylesheet" href="../../plugins/element-ui/index.css" />
      <link rel="stylesheet" href="../../styles/common.css" />
      <link rel="stylesheet" href="../../styles/page.css" />
    head>
    <body>
       <div class="addBrand-container" id="food-add-app">
        <div class="container">
            <el-upload class="avatar-uploader"
                    action="/common/upload"
                    :show-file-list="false"
                    :on-success="handleAvatarSuccess"
                    :before-upload="beforeUpload"
                    ref="upload">
                <img v-if="imageUrl" :src="imageUrl" class="avatar">img>
                <i v-else class="el-icon-plus avatar-uploader-icon">i>
            el-upload>
        div>
      div>
        
        <script src="../../plugins/vue/vue.js">script>
        
        <script src="../../plugins/element-ui/index.js">script>
        
        <script src="../../plugins/axios/axios.min.js">script>
        <script src="../../js/index.js">script>
        <script>
          new Vue({
            el: '#food-add-app',
            data() {
              return {
                imageUrl: ''
              }
            },
            methods: {
              handleAvatarSuccess (response, file, fileList) {
                  this.imageUrl = `/common/download?name=${response.data}`
              },
              beforeUpload (file) {
                if(file){
                  const suffix = file.name.split('.')[1]
                  const size = file.size / 1024 / 1024 < 2
                  if(['png','jpeg','jpg'].indexOf(suffix) < 0){
                    this.$message.error('上传图片只支持 png、jpeg、jpg 格式!')
                    this.$refs.upload.clearFiles()
                    return false
                  }
                  if(!size){
                    this.$message.error('上传文件大小不能超过 2MB!')
                    return false
                  }
                  return file
                }
              }
            }
          })
        script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66


    5. 相应配置

    编辑 src/main/resources/application.yml 文件:

    ...
    
    reggie:
      path: D\img\
    
    • 1
    • 2
    • 3
    • 4

    新建 src/test/java/UploadFileTest.java 文件:

    import org.junit.jupiter.api.Test;
    
    public class UploadFileTest {
        @Test
        public void text1(){
            String fileName = "hello.jpg";
            String suffix = fileName.substring(fileName.lastIndexOf("."));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9


    6. 控制器方法

    (结)编辑 src/main/java/com/reggie/controller/CommonController.java 类:

    package com.reggie.controller;
    
    import com.reggie.common.R;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.util.UUID;
    
    /**
     * 文件的上传和下载
     */
    @RestController
    @RequestMapping("/common")
    @Slf4j
    public class CommonController {
        @Value("${reggie.path}")
        private String basePath;
    
        /**
         * 文件上传
         * @param file
         * @return
         */
        @PostMapping("/upload")
        public R<String> upload(MultipartFile file  ) {
            log.info(file.toString());
    
            // 获取原始文件文件名
            String originalFilename = file.getOriginalFilename();
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
    
            // 使用 UUID重新生成文件名,防止文件名称重复造成we文件覆盖
            String fileName = UUID.randomUUID().toString() + suffix;
    
            // 创建一个目录对象
            File dir = new File(basePath);
            // 判断当前目录是否存在
            if(!dir.exists()) {
                // 目录不存在,需要创建
                dir.mkdirs();
            }
    
            // 将临时文件转存到指定路径
            try {
                file.transferTo(new File(basePath + fileName));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
    
            return R.success(fileName);
        }
    
        /**
         * 文件下载
         * @param name
         * @param response
         */
        @GetMapping("/download")
        public void download(String name, HttpServletResponse response) {
            try {
                // 输入流,读取文件内容
                FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));
    
                // 输出流,通过输出流将文件写回浏览器
                ServletOutputStream outputStream = response.getOutputStream();
    
                response.setContentType("image/jpeg");
    
                int len = 0;
                byte[] bytes = new byte[1024];
                while ((len = fileInputStream.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, len);
                    outputStream.flush();
                }
    
                // 关闭资源
                fileInputStream.close();
                outputStream.close();
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96




    二、新增菜品

    1. 界面预览

    在这里插入图片描述


    2. 基础搭建

    ⑴. 实体类

    新建 src/main/java/com/reggie/entity/DishFlavor 类:

    package com.reggie.entity;
    
    import com.baomidou.mybatisplus.annotation.FieldFill;
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import lombok.Data;
    import java.io.Serializable;
    import java.time.LocalDateTime;
    
    /**
    菜品口味
     */
    @Data
    public class DishFlavor implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        private Long id;
    
    
        //菜品id
        private Long dishId;
    
    
        //口味名称
        private String name;
    
    
        //口味数据list
        private String value;
    
    
        @TableField(fill = FieldFill.INSERT)
        private LocalDateTime createTime;
    
    
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private LocalDateTime updateTime;
    
    
        @TableField(fill = FieldFill.INSERT)
        private Long createUser;
    
    
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private Long updateUser;
    
    
        //是否删除
        private Integer isDeleted;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    ⑵. Mapper 接口

    新建 src/main/java/com/reggie/mapper/DishFlavorMapper 接口:

    package com.reggie.mapper;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.reggie.entity.DishFlavor;
    import org.apache.ibatis.annotations.Mapper;
    
    @Mapper
    public interface DishFlavorMapper extends BaseMapper<DishFlavor> {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    ⑶. Service 接口

    新建 src/main/java/com/reggie/service/DishFlavorService 类:

    package com.reggie.service;
    
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.reggie.entity.DishFlavor;
    
    public interface DishFlavorService extends IService<DishFlavor> {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ⑷. Service 实现类

    新建 src/main/java/com/reggie/service/impl/DishFlavorServiceImpl 类:

    package com.reggie.service.impl;
    
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.reggie.entity.DishFlavor;
    import com.reggie.mapper.DishFlavorMapper;
    import com.reggie.service.DishFlavorService;
    import org.springframework.stereotype.Service;
    
    @Service
    public class DishFlavorServiceImpl extends ServiceImpl<DishFlavorMapper, DishFlavor> implements DishFlavorService {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11


    3. 控制器

    ⑴. 菜品分类下拉

    编辑 src/main/java/com/reggie/controller/CategoryController 类:

        ...
    
        /**
         * 根据条件查询分类数据
         * @param category
         * @return
         */
        @GetMapping("/list")
        public R<List<Category>> list(Category category) {
            // 条件构造器
            LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
            // 添加条件
            queryWrapper.eq(category.getType() != null, Category::getType, category.getType());
            // 添加条件排序
            queryWrapper.orderByAsc(Category::getSort).orderByDesc(Category::getUpdateTime);
            List<Category> list = categoryService.list(queryWrapper);
            return R.success(list);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    ⑵. 导入 DTO

    新建 src/main/java/com/reggie/dto/DishDto 类,用于封装页面提交的数据:

    package com.reggie.dto;
    
    import com.reggie.entity.Dish;
    import com.reggie.entity.DishFlavor;
    import lombok.Data;
    import java.util.ArrayList;
    import java.util.List;
    
    @Data
    public class DishDto extends Dish {
    
        private List<DishFlavor> flavors = new ArrayList<>();
    
        private String categoryName;
    
        private Integer copies;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    ⑶. 项目启动类

    新增菜品时,需要向 dish 、 dish_flavor 两个表插入数据,为了保证数据一致性,需要启动事物管理

    编辑 src/main/java/com/reggie/ReggieApplication 类:

    //启动类
    package com.reggie;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    @Slf4j
    @SpringBootApplication
    @ServletComponentScan
    @EnableTransactionManagement
    public class ReggieApplication {
        public static void main(String[] args) {
            SpringApplication.run(ReggieApplication.class, args);
            log.info("项目启动成功...");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    ⑷. 新增菜品

    新增 src/main/java/com/reggie/controller/DishController 类:

    package com.reggie.controller;
    
    import ...
    
    /**
     * 菜品管理
     */
    @RestController
    @RequestMapping("/dish")
    @Slf4j
    public class DishController {
    
        /**
         * 新增菜品
         * @param dishDto
         * @return
         */
        @PostMapping
        public R<String> save(@RequestBody DishDto dish) {
            log.info("dish: {}", dish);
    
            return R.success("新增菜品成功");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    ⑸. 拓展 saveWithFlavor 方法

    新建 src/main/java/com/reggie/service/DishService 类:

    package com.reggie.service;
    
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.reggie.dto.DishDto;
    import com.reggie.entity.Dish;
    
    public interface DishService extends IService<Dish> {
        // 新增菜品,同时插入菜品的口味数据,需要操作两张表:dish, dish_flavor
        public void saveWithFlavor(DishDto dishDto);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    ⑹. 实现 saveWithFlavor 方法

    新建 src/main/java/com/reggie/service/impl/DishServiceImpl 类:

    package com.reggie.service.impl;
    
    import ...
    
    @Service
    @Slf4j
    public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
        @Autowired
        private DishFlavorService dishFlavorService;
    
        @Autowired
        private DishService dishService;
        
        /**
         * 新增菜品,同时保存对应的口味数据
         * @param dishDto
         */
        @Override
        @Transactional
        public void saveWithFlavor(DishDto dishDto) {
            // 保存菜品的基本信息到菜品表 dish
            this.save(dishDto);
    
            Long dishId = dishDto.getId(); // 菜品
            List<DishFlavor> flavors = dishDto.getFlavors(); // 菜品口味
            // 菜品口味集合
            flavors = flavors.stream().map((item) -> {
                item.setDishId(dishId);
                return item;
            }).collect(Collectors.toList());
    
            // 保存菜品口味数据到菜品口味数据表 dish_flavor
            // dishFlavorService.saveBatch(dishDto.getFlavors());
            dishFlavorService.saveBatch(flavors);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    ⑺. 完善控制层

    编辑 src/main/java/com/reggie/controller/DishController 类:

    package com.reggie.controller;
    
    import ...
    
    /**
     * 菜品管理
     */
    @RestController
    @RequestMapping("/dish")
    @Slf4j
    public class DishController {
    
        @Autowired
        private DishService dishService;
    
        @Autowired
        private DishFlavorService dishFlavorService;
    
        @Autowired
        private CategoryService categoryService;
    
        /**
         * 新增菜品
         * @param dishDto
         * @return
         */
        @PostMapping
        public R<String> save(@RequestBody DishDto dishDto) {
            log.info(dishDto.toString());
    
            dishService.saveWithFlavor(dishDto);
            return R.success("新增菜品成功");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34




    三、分页查询

    1. 界面预览

    在这里插入图片描述



    2. 编码实现

    编辑 src/main/java/com/reggie/controller/DishController 类:

        ...
    
        /**
         * 菜品信息分页查询
         * @param page
         * @param pageSize
         * @param name
         * @return
         */
        @GetMapping("/page")
        public R<Page> page(int page, int pageSize, String name) {
            // 构造分页器对象
            Page<Dish> pageInfo = new Page<>(page, pageSize);
            Page<DishDto> dishDtoPage = new Page<>();
    
            // 构造条件查询
            LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
    
            // 添加过滤条件
            queryWrapper.like(name != null, Dish::getName, name);
    
            // 添加排序条件
            queryWrapper.orderByDesc(Dish::getUpdateTime);
    
            // 执行分页查询
            dishService.page(pageInfo, queryWrapper);
    
            // 对象拷贝
            BeanUtils.copyProperties(pageInfo, dishDtoPage, "records");
    
            List<Dish> records = pageInfo.getRecords();
            List<DishDto> list = records.stream().map((item) -> {
                DishDto dishDto = new DishDto();
    
                // 拷贝普通属性到 dishDto 对象中
                BeanUtils.copyProperties(item, dishDto);
    
                Long categoryId = item.getCategoryId(); // 分类 ID
                // 根据 ID 查询分类对象
                Category category = categoryService.getById(categoryId);
                if(category != null) {
                    String categoryName = category.getName();
                    dishDto.setCategoryName(categoryName);
                }
                return dishDto;
            }).collect(Collectors.toList());
    
            dishDtoPage.setRecords(list);
    
            return R.success(pageInfo);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52




    四、修改菜品

    1. 界面预览

    在这里插入图片描述



    2. 编码实现

    ⑴. 拓展 getByIdWithFlavor 方法

    新建 src/main/java/com/reggie/service/DishService 类:

    package com.reggie.service;
    
    import ...
    
    public interface DishService extends IService<Dish> {
        // 新增菜品,同时插入菜品的口味数据,需要操作两张表:dish, dish_flavor
        public void saveWithFlavor(DishDto dishDto);
    
        // 根据 id 查询菜品信息和对应的口味信息
        public DishDto getByIdWithFlavor(Long id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    ⑵. 实现 getByIdWithFlavor 方法

    新建 src/main/java/com/reggie/service/impl/DishServiceImpl 类:

        ...
    
        /**
         * 根据 id 查询菜品信息和口味信息
         * @param id
         * @return
         */
        @Override
        public DishDto getByIdWithFlavor(Long id) {
    
            // 查询菜品的基本信息 dish
            Dish dish = this.getById(id);
    
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(dish, dishDto);
    
            // 查询当前菜品的口味信息 dish_flavor
            LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DishFlavor::getDishId, dish.getId());
            List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);
    
            dishDto.setFlavors(flavors);
    
            return dishDto;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    ⑶. 创建 get 方法

    编辑 src/main/java/com/reggie/controller/DishController 类:

        ...
        
        /**
         * 根据 id 查询菜品信息和对应的口味信息
         * @param id
         * @return
         */
        @GetMapping("/{id}")
        public R<DishDto> get(@PathVariable Long id) {
            DishDto dishDto = dishService.getByIdWithFlavor(id);
            return R.success(dishDto);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    ⑷. 创建 updateWithFlavor 方法

    新建 src/main/java/com/reggie/service/DishService 类:

    package com.reggie.service;
    
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.reggie.dto.DishDto;
    import com.reggie.entity.Dish;
    
    public interface DishService extends IService<Dish> {
        // 新增菜品,同时插入菜品的口味数据,需要操作两张表:dish, dish_flavor
        public void saveWithFlavor(DishDto dishDto);
    
        // 根据 id 查询菜品信息和对应的口味信息
        public DishDto getByIdWithFlavor(Long id);
    
        // 更新菜品信息,同时更新对应的口味信息
        public void updateWithFlavor(DishDto dishDto);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    ⑸. 实现 updateWithFlavor 方法

    新建 src/main/java/com/reggie/service/impl/DishServiceImpl 类:

    package com.reggie.service.impl;
    
    import ...
    
    @Service
    @Slf4j
    public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
        @Autowired
        private DishFlavorService dishFlavorService;
    
        @Autowired
        private DishService dishService;
        /**
         * 新增菜品,同时保存对应的口味数据
         * @param dishDto
         */
        @Override
        @Transactional
        public void saveWithFlavor(DishDto dishDto) {
            // 保存菜品的基本信息到菜品表 dish
            this.save(dishDto);
    
            Long dishId = dishDto.getId(); // 菜品
            List<DishFlavor> flavors = dishDto.getFlavors(); // 菜品口味
            // 菜品口味集合
            flavors = flavors.stream().map((item) -> {
                item.setDishId(dishId);
                return item;
            }).collect(Collectors.toList());
    
            // 保存菜品口味数据到菜品口味数据表 dish_flavor
            // dishFlavorService.saveBatch(dishDto.getFlavors());
            dishFlavorService.saveBatch(flavors);
        }
    
        /**
         * 根据 id 查询菜品信息和口味信息
         * @param id
         * @return
         */
        @Override
        public DishDto getByIdWithFlavor(Long id) {
    
            // 查询菜品的基本信息 dish
            Dish dish = this.getById(id);
    
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(dish, dishDto);
    
            // 查询当前菜品的口味信息 dish_flavor
            LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DishFlavor::getDishId, dish.getId());
            List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);
    
            dishDto.setFlavors(flavors);
    
            return dishDto;
        }
    
        /**
         * 修改菜品信息
         * @param dishDto
         */
        @Override
        @Transactional
        public void updateWithFlavor(DishDto dishDto) {
            // 更新 dish 表的基本信息
            this.updateById(dishDto);
    
            // 清理当前菜品对应的口味数据 dish_flavor 的 delete 操作
            LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DishFlavor::getDishId, dishDto.getId());
            dishFlavorService.remove(queryWrapper);
    
            // 添加传递过来的口味数据 dish_flavor 的 insert 操作
            List<DishFlavor> flavors = dishDto.getFlavors();
            flavors = flavors.stream().map((item) -> {
                item.setDishId(dishDto.getId());
                return item;
            }).collect(Collectors.toList());
            dishFlavorService.saveBatch(flavors);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    ⑹. 完善控制层

    编辑 src/main/java/com/reggie/controller/DishController 类:

        ...
    
        /**
         * 修改菜品
         * @param dishDto
         * @return
         */
        @PutMapping
        public R<String> update(@RequestBody DishDto dishDto) {
            log.info(dishDto.toString());
    
            dishService.updateWithFlavor(dishDto);
            return R.success("修改菜品成功");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15


  • 相关阅读:
    企业级前端组件建设
    黔院长 | 做好大健康产业的前提——有真正的技术和经验!
    sharepoint2016-2019升级到sharepoint订阅版
    芯科蓝牙BG27开发笔记9-资料整理
    PSCA电源控制集成之分布式PPU
    基于交叉算子和非均匀变异算子的飞蛾扑火优化算法-附代码
    XSS-labs靶场实战(三)——第7-8关
    如何使用NPM包管理器在Node.js项目中安装和管理依赖
    4、 后台服务配制以及代码生成[木字楠博客]
    淘宝商品详情API接口(H5端和APP端),淘宝详情页,商品属性接口,商品信息查询
  • 原文地址:https://blog.csdn.net/weixin_45137565/article/details/126371390