企业培训笔记:外卖平台后端--套餐管理模块--新建套餐信息

文章目录


新建套餐信息

在外卖管理系统中,新建套餐是核心功能之一。新建套餐不仅需要保存套餐的基本信息(如名称、所属分类、价格、图片等),还必须同步保存"套餐与菜品的关联关系"(即该套餐包含哪些菜品、每种菜品的数量)。下方图片展示的是新建套餐的前端操作界面,界面中清晰划分了"套餐基本信息填写区"和"菜品选择区",用户完成信息录入后提交,后端将通过以下步骤处理请求。

(一)SetmealMapper接口添加方法

Mapper接口是数据访问层的入口,新建套餐首先需要定义"插入套餐基本信息"的方法。这里通过注解和自定义注解结合,简化开发并保证公共字段的自动填充。

java 复制代码
/**                            
 * 新增套餐(仅插入套餐基本信息,不包含关联菜品)                        
 * @param setmeal  封装了套餐基本信息的实体类(如名称、分类ID、价格等)              
 */                            
@AutoFill(OperationType.INSERT)
void insert(Setmeal setmeal);  
  • @AutoFill(OperationType.INSERT) :这是自定义的"自动填充注解",作用是在执行插入操作时,自动为Setmeal实体的公共字段(如createTime创建时间、updateTime修改时间、createUser创建人、updateUser修改人)赋值,无需手动编写代码,减少重复工作。
  • 方法作用 :仅负责将套餐的基本信息插入到setmeal表中,关联菜品的插入会由其他方法处理。

(二)SetmealMapper.xml文件添加sql语句

Mapper接口的insert方法需要通过XML编写具体的SQL,同时配置"获取自动生成的主键"------因为后续关联菜品时,需要用这个主键(套餐ID)绑定关系。

xml 复制代码
<!-- 新增套餐信息(插入套餐基本数据到setmeal表) -->                                                                                                 
<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>                                                                                                       
  • 关键配置解析
    1. useGeneratedKeys="true":开启"获取数据库自动生成的主键"功能(适用于主键自增的表,如setmeal表的id字段)。
    2. keyProperty="id":将数据库生成的主键值,赋值给Setmeal实体的id属性------后续通过setmeal.getId()就能拿到新建套餐的ID,用于关联菜品。
    3. SQL字段说明:category_id对应套餐所属分类ID,status表示套餐状态(0下架/1起售),image是套餐封面图的路径,其余字段为自动填充的公共字段。

(三)SetmealService业务层接口添加方法

Service层负责封装业务逻辑,新建套餐的核心业务是"同时保存套餐基本信息和套餐-菜品关联关系",因此定义saveWithDish方法("WithDish"强调包含菜品关联)。

java 复制代码
/**                                       
 * 新增套餐,同时保存套餐和菜品的关联关系                  
 * @param setmealDTO  封装了"套餐基本信息+关联菜品列表"的DTO(数据传输对象)                      
 */                                       
void saveWithDish(SetmealDTO setmealDTO); 
  • 为什么用SetmealDTO而非Setmeal
    Setmeal实体仅对应setmeal表的字段,而前端提交的请求中,除了套餐基本信息,还包含setmealDishes(关联的菜品列表,如"鱼香肉丝x2份""米饭x1份")。SetmealDTOSetmeal基础上新增了setmealDishes属性,刚好能接收前端的完整数据,避免用多个参数传递。

(四)SetmealServiceImpl接口实现类重写方法

Service实现类是业务逻辑的核心执行层,这里需要通过事务控制保证"套餐插入"和"关联菜品插入"同时成功或失败,避免数据不一致(比如套餐插成功了,但关联菜品没插,导致套餐是空的)。

java 复制代码
/**                                                                 
 * 新增套餐,同时保存套餐和菜品的关联关系                                            
 * @param setmealDTO  前端传递的完整套餐数据(基本信息+关联菜品)                
 */                                                                 
@Transactional  // 事务注解:确保以下操作要么全成功,要么全回滚(比如关联菜品插入失败,套餐也会回滚删除)                                                      
public void saveWithDish(SetmealDTO setmealDTO) {                   
    // 1. 将DTO转成Setmeal实体(用于插入套餐基本信息)                                
    Setmeal setmeal = new Setmeal();                                
    // 2. 设置公共字段(这里手动设置,也可通过@AutoFill注解自动填充,视项目配置而定)                          
    setmeal.setCreateTime(LocalDateTime.now());  // 创建时间设为当前时间                     
    setmeal.setUpdateTime(LocalDateTime.now());  // 修改时间设为当前时间                     
    setmeal.setCreateUser(BaseContext.getCurrentId());  // 创建人:从上下文拿当前登录用户ID              
    setmeal.setUpdateUser(BaseContext.getCurrentId());  // 修改人:同创建人              
    // 3. 插入套餐基本信息到setmeal表(调用Mapper方法)                                                      
    setmealMapper.insert(setmeal);                                  
    // 4. 获取新建套餐的ID(由Mapper的XML配置自动赋值到setmeal的id属性)                                                     
    Long setmealId = setmeal.getId();                               
    // 5. 处理关联菜品列表:给每个菜品绑定套餐ID(否则关联表不知道菜品属于哪个套餐)                        
    List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
    setmealDishes.forEach(setmealDish -> {  // 遍历所有关联菜品                          
        setmealDish.setSetmealId(setmealId);  // 给当前菜品设置套餐ID                        
    });                                                             
    // 6. 批量插入关联数据到setmeal_dish表(批量插入比循环单条插入效率更高)                                                  
    setmealDishMapper.insertBatch(setmealDishes);                   
}                                                                   
  • 核心步骤拆解
    1. DTO转实体 :因为setmealMapper.insert需要Setmeal类型参数,所以先创建Setmeal对象,用于存储基本信息。
    2. 公共字段赋值BaseContext.getCurrentId()是从ThreadLocal中获取当前登录用户的ID(比如管理员ID),确保操作人信息准确。
    3. 获取套餐ID :插入套餐后,通过setmeal.getId()拿到数据库自动生成的ID,这是关联菜品的关键。
    4. 绑定关联关系 :遍历前端传的setmealDishes,给每个菜品设置setmealId,相当于给"菜品"贴了"所属套餐"的标签。
    5. 批量插入关联数据 :用insertBatch批量插入关联表,减少数据库交互次数,提升性能。

(五)SetmealController控制层类添加方法

Controller层是前端请求的入口,负责接收前端提交的套餐数据、调用Service层执行业务、清理缓存(保证数据最新),并返回结果给前端。

java 复制代码
/**                                                                    
 * 新增套餐(接收前端请求并响应)                                                                
 * @param setmealDTO  前端以JSON格式提交的"套餐基本信息+关联菜品"数据                                                   
 * @return  统一响应结果(告知前端新增成功)                                                             
 */                                                                    
@PostMapping  // 用POST请求处理"新增"操作(符合HTTP语义,POST用于提交数据)                                                            
@ApiOperation("新增套餐")  // Swagger注解:生成接口文档时说明接口功能                                                  
@CacheEvict(cacheNames = "setmealCache",key = "#setmealDTO.categoryId")  // 清理缓存:避免前端拿到旧的套餐列表
public Result save(@RequestBody SetmealDTO setmealDTO) {               
    // 调用Service层的核心业务方法,执行新增逻辑                           
    setmealService.saveWithDish(setmealDTO);                           
    // 返回成功响应:前端收到后会提示"新增成功",并刷新套餐列表                                           
    return Result.success();                                           
}                                                                      
  • 关键注解说明
    1. @RequestBody SetmealDTO setmealDTO:将前端提交的JSON数据,自动转化为SetmealDTO对象,无需手动解析JSON。
    2. @CacheEvict:清理缓存的注解。如果系统缓存了"某个分类下的套餐列表"(比如cacheNames="setmealCache"key是分类ID),新增套餐后需要清空该分类的缓存,避免前端刷新后仍显示旧列表(比如新增"快餐"分类的套餐后,"快餐"列表要实时更新)。
    3. Result.success():统一响应格式,前端收到后会触发"新增成功"的提示(如弹窗提示),并重新加载套餐列表,展示新建的套餐。

通过以上步骤,前端提交新建套餐的请求后,后端会完整完成"套餐基本信息插入"和"套餐-菜品关联插入",同时保证数据一致性和缓存时效性,最终实现新建套餐的功能。

相关推荐
degen_5 小时前
第一次进入 PEICORE 流程
c语言·笔记
YJlio5 小时前
Process Monitor 学习笔记(5.24):工具栏参考与高效快捷键指南
笔记·学习·php
摇滚侠6 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 核心语法 笔记39
spring boot·笔记·后端·thymeleaf
张人玉6 小时前
WPF 常用样式属性及示例笔记
笔记·wpf
报错小能手7 小时前
linux学习笔记(49)Redis详解(1)
linux·笔记·学习
QT 小鲜肉7 小时前
【个人成长笔记】在本地Windows系统中如何正确使用adb pull命令,把Linux系统中的文件或文件夹复制到本地中(亲测有效)
linux·windows·笔记·学习·adb
John.Lewis9 小时前
C++初阶(14)list
开发语言·c++·笔记
_李小白9 小时前
【OPENGL ES 3.0 学习笔记】第九天:缓存、顶点和顶点数组
笔记·学习·elasticsearch
信仰_27399324310 小时前
Mybatis-Spring重要组件介绍
java·spring·mybatis