文章目录
- 回显套餐信息
-
- (一)SetmealMapper接口添加方法
- (二)SetmealMapper.xml文件添加sql语句
-
- [1. 定义resultMap(映射规则)](#1. 定义resultMap(映射规则))
- [2. 编写查询SQL](#2. 编写查询SQL)
- (三)SetmealService业务层接口添加方法
- (四)SetmealServiceImpl接口实现类重写方法
- (五)SetmealController控制层类添加方法
回显套餐信息
在套餐管理中,当用户点击"修改"按钮时,系统需要将该套餐的现有信息(包括套餐基本信息和包含的菜品)自动填充到修改框中,方便用户在原有信息基础上编辑。这个"自动填充"的过程就是"回显"。下面我们一步步实现套餐信息的回显功能。

首先看实际效果:
-
点击【修改】按钮后,会弹出修改框,理想状态下,框中应自动显示该套餐当前的信息(如套餐名称、分类、价格,以及包含的菜品和数量等)。
-
但刚开始,修改框是空白的,无法回显信息,需要通过编写代码,让系统查询并展示这些数据。
(一)SetmealMapper接口添加方法
要回显套餐信息,首先需要从数据库中查询套餐的完整数据------不仅包括套餐本身的基本信息(如名称、分类ID、状态等),还包括该套餐关联的所有菜品(如菜品ID、名称、数量等)。因此,我们在SetmealMapper
接口中定义一个专门的查询方法。

java
/**
* 根据id查询套餐和套餐关联的菜品
* @param id 套餐的ID(用于定位具体套餐)
* @return 包含套餐基本信息和关联菜品的SetmealVO对象
*/
SetmealVO getByIdWithDish(Long id);
- 为什么用SetmealVO ?
SetmealVO
是视图对象,专门用于封装前端需要展示的数据。它不仅包含Setmeal
(套餐基本信息)的字段,还额外添加了setmealDishes
属性(用于存储套餐关联的菜品列表),刚好满足回显时"既要看套餐信息,又要看包含的菜品"的需求。
(二)SetmealMapper.xml文件添加sql语句
有了查询方法的声明,还需要编写SQL语句来执行查询,并通过resultMap
将查询结果正确映射到SetmealVO
对象中(因为涉及套餐和菜品的关联数据,需要手动配置映射关系)。
1. 定义resultMap(映射规则)

xml
<!-- 定义套餐和关联菜品的映射规则,type指定最终封装成SetmealVO -->
<resultMap id="setmealAndDishMap" type="com.sky.vo.SetmealVO" autoMapping="true">
<!-- 映射套餐的id(主键),column是数据库字段名,property是SetmealVO的属性名 -->
<result column="id" property="id"/>
<!-- 映射套餐关联的菜品列表:property是SetmealVO中的setmealDishes属性(List类型),ofType是列表中元素的类型(SetmealDish) -->
<collection property="setmealDishes" ofType="SetmealDish">
<!-- 映射关联表中的字段到SetmealDish的属性,注意别名避免和套餐表字段冲突(如用sd_id代表关联表的id) -->
<result column="sd_id" property="id"/>
<result column="setmeal_id" property="setmealId"/>
<result column="dish_id" property="dishId"/>
<result column="sd_name" property="name"/> <!-- sd_name是关联表中菜品名称的别名 -->
<result column="sd_price" property="price"/> <!-- sd_price是关联表中菜品价格的别名 -->
<result column="copies" property="copies"/> <!-- 菜品数量 -->
</collection>
</resultMap>
- 核心作用 :
套餐表(setmeal
)和套餐-菜品关联表(setmeal_dish
)有多个字段名可能重复(如id
、name
、price
),通过resultMap
可以明确指定"数据库字段对应到Java对象的哪个属性",尤其是通过<collection>
标签,将关联表的多条菜品数据封装成List<SetmealDish>
,存入SetmealVO
的setmealDishes
属性中。
2. 编写查询SQL

xml
<!-- 根据id查询套餐信息与套餐关联的菜品,id对应Mapper接口的getByIdWithDish方法,resultMap指定用上面定义的映射规则 -->
<select id="getByIdWithDish" parameterType="long" resultMap="setmealAndDishMap">
select a.*, <!-- a代表套餐表setmeal,查询所有套餐字段 -->
b.id sd_id, <!-- b代表关联表setmeal_dish,给id起别名sd_id,避免和套餐表id冲突 -->
b.setmeal_id, <!-- 套餐ID(关联表中的外键) -->
b.dish_id, <!-- 菜品ID(关联表中的外键) -->
b.name sd_name, <!-- 关联表中的菜品名称,起别名sd_name -->
b.price sd_price, <!-- 关联表中的菜品价格,起别名sd_price -->
b.copies <!-- 该菜品在套餐中的数量 -->
from setmeal a
left join <!-- 左连接套餐表和关联表,确保即使套餐暂时没有菜品也能查询到套餐信息 -->
setmeal_dish b
on <!-- 关联条件:套餐表的id = 关联表的setmeal_id -->
a.id = b.setmeal_id
where a.id = #{id} <!-- 只查询指定ID的套餐 -->
</select>
- 查询逻辑 :
通过left join
关联setmeal
(套餐表)和setmeal_dish
(套餐-菜品关联表),一次性查询出套餐的基本信息和所有关联的菜品信息,再通过前面定义的resultMap
,将这些数据正确封装到SetmealVO
中,供后续使用。
(三)SetmealService业务层接口添加方法
Service层作为业务逻辑的中间层,需要定义一个接口方法,供Controller调用,获取包含关联菜品的套餐信息。

java
/**
* 根据id查询套餐和关联的菜品数据(供回显使用)
* @param id 套餐ID
* @return 包含完整信息的SetmealVO对象
*/
SetmealVO getByIdWithDish(Long id);
- 作用:封装数据访问层的查询逻辑,为Controller提供统一的调用入口,后续如果需要添加业务逻辑(如权限校验),可以直接在这里扩展。
(四)SetmealServiceImpl接口实现类重写方法
Service实现类负责具体的业务逻辑,这里主要是调用Mapper层的方法,获取查询结果并返回。

java
/**
* 根据id查询套餐和套餐关联菜品(实现回显的核心数据查询)
* @param id 套餐ID
* @return 包含套餐和菜品信息的SetmealVO
*/
public SetmealVO getByIdWithDish(Long id) {
// 直接调用Mapper的查询方法,获取数据并返回给Controller
SetmealVO setmealVO = setmealMapper.getByIdWithDish(id);
return setmealVO;
}
- 逻辑说明 :当前业务逻辑较简单,直接通过
setmealMapper.getByIdWithDish(id)
获取数据即可。如果后续有复杂需求(如数据脱敏、额外字段计算),可以在这里处理后再返回。
(五)SetmealController控制层类添加方法
Controller层负责接收前端的"查询回显数据"请求,调用Service层获取数据,再将数据返回给前端,供修改框渲染使用。

java
/**
* 根据id查询套餐,用于修改页面回显数据
* @param id 从URL路径中获取的套餐ID(如/admin/setmeal/1中的1)
* @return 包含回显数据的统一响应结果
*/
@GetMapping("/{id}") // 接收GET请求,路径中的{id}对应方法参数id
@ApiOperation("根据id查询套餐(用于回显)")
public Result<SetmealVO> getById(@PathVariable Long id) {
// 调用Service获取包含菜品的套餐信息
SetmealVO setmealVO = setmealService.getByIdWithDish(id);
// 将数据封装到统一响应对象Result中返回给前端(前端拿到后渲染到修改框)
return Result.success(setmealVO);
}
- 关键说明 :
@GetMapping("/{id}")
:前端通过/admin/setmeal/套餐ID
的路径发送请求(如/admin/setmeal/3
查询ID为3的套餐),{id}
会被@PathVariable
注解捕获,作为方法参数。- 返回
Result.success(setmealVO)
:前端收到响应后,从Result
中取出setmealVO
数据,将套餐名称、分类、价格等填充到表单,同时将关联的菜品列表渲染到页面(如显示"鱼香肉丝 x 2份"),完成回显。
通过以上步骤,当用户再次点击"修改"按钮时,前端会调用该接口获取数据,修改框就能自动回显套餐的所有信息,方便用户进行编辑修改了。