1.4.3 测试
访问页面 http://localhost:8080/backend/page/demo/upload.html , 点击上传图片 , 选择图片进行上传, 上传完毕之后, 查看图片是否可以展示出来。
通过F12查询页面发起的请求及响应的数据:
2. 菜品新增
2.1 需求分析
2.2 数据模型
新增菜品,其实就是将新增页面录入的菜品信息插入到dish表,如果添加了口味做法,还需要向dish_flavor表插入数据。所以在新增菜品时,涉及到两个表:
表结构 | 说明 |
dish | 菜品表 |
dish_flavor | 菜品口味表 |
2.3 准备工作
在开发业务功能前,先将需要用到的类和接口基本结构创建好:
1). 实体类 DishFlavor
直接从课程资料中导入即可,Dish实体前面课程中已经导入过了
所属包: com.itheima.reggie.entity
1.<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">baomidou</span>.<span style="color:#000000">mybatisplus</span>.<span style="color:#000000">annotation</span>.<span style="color:#000000">FieldFill</span>; <span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">baomidou</span>.<span style="color:#000000">mybatisplus</span>.<span style="color:#000000">annotation</span>.<span style="color:#000000">TableField</span>; <span style="color:#770088">import</span> <span style="color:#000000">lombok</span>.<span style="color:#000000">Data</span>; <span style="color:#770088">import</span> <span style="color:#000000">java</span>.<span style="color:#000000">io</span>.<span style="color:#000000">Serializable</span>; <span style="color:#770088">import</span> <span style="color:#000000">java</span>.<span style="color:#000000">time</span>.<span style="color:#000000">LocalDateTime</span>; <span style="color:#aa5500">/**</span> <span style="color:#aa5500">菜品口味</span> <span style="color:#aa5500">*/</span> <span style="color:#555555">@Data</span> <span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">DishFlavor</span> <span style="color:#770088">implements</span> <span style="color:#000000">Serializable</span> { <span style="color:#770088">private</span> <span style="color:#770088">static</span> <span style="color:#770088">final</span> <span style="color:#008855">long</span> <span style="color:#000000">serialVersionUID</span> <span style="color:#981a1a">=</span> <span style="color:#116644">1L</span>; <span style="color:#770088">private</span> <span style="color:#008855">Long</span> <span style="color:#000000">id</span>; <span style="color:#aa5500">//菜品id</span> <span style="color:#770088">private</span> <span style="color:#008855">Long</span> <span style="color:#000000">dishId</span>; <span style="color:#aa5500">//口味名称</span> <span style="color:#770088">private</span> <span style="color:#008855">String</span> <span style="color:#000000">name</span>; <span style="color:#aa5500">//口味数据list</span> <span style="color:#770088">private</span> <span style="color:#008855">String</span> <span style="color:#000000">value</span>; <span style="color:#555555">@TableField</span>(<span style="color:#000000">fill</span> <span style="color:#981a1a">=</span> <span style="color:#000000">FieldFill</span>.<span style="color:#000000">INSERT</span>) <span style="color:#770088">private</span> <span style="color:#000000">LocalDateTime</span> <span style="color:#000000">createTime</span>; <span style="color:#555555">@TableField</span>(<span style="color:#000000">fill</span> <span style="color:#981a1a">=</span> <span style="color:#000000">FieldFill</span>.<span style="color:#000000">INSERT_UPDATE</span>) <span style="color:#770088">private</span> <span style="color:#000000">LocalDateTime</span> <span style="color:#000000">updateTime</span>; <span style="color:#555555">@TableField</span>(<span style="color:#000000">fill</span> <span style="color:#981a1a">=</span> <span style="color:#000000">FieldFill</span>.<span style="color:#000000">INSERT</span>) <span style="color:#770088">private</span> <span style="color:#008855">Long</span> <span style="color:#000000">createUser</span>; <span style="color:#555555">@TableField</span>(<span style="color:#000000">fill</span> <span style="color:#981a1a">=</span> <span style="color:#000000">FieldFill</span>.<span style="color:#000000">INSERT_UPDATE</span>) <span style="color:#770088">private</span> <span style="color:#008855">Long</span> <span style="color:#000000">updateUser</span>; <span style="color:#aa5500">//是否删除</span> <span style="color:#770088">private</span> <span style="color:#008855">Integer</span> <span style="color:#000000">isDeleted</span>; }</span></span>
2). Mapper接口DishFlavorMapper
所属包: com.itheima.reggie.mapper
1.<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">baomidou</span>.<span style="color:#000000">mybatisplus</span>.<span style="color:#000000">core</span>.<span style="color:#000000">mapper</span>.<span style="color:#000000">BaseMapper</span>; <span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">itheima</span>.<span style="color:#000000">reggie</span>.<span style="color:#000000">entity</span>.<span style="color:#000000">DishFlavor</span>; <span style="color:#770088">import</span> <span style="color:#000000">org</span>.<span style="color:#000000">apache</span>.<span style="color:#000000">ibatis</span>.<span style="color:#000000">annotations</span>.<span style="color:#000000">Mapper</span>; <span style="color:#555555">@Mapper</span> <span style="color:#770088">public</span> <span style="color:#770088">interface</span> <span style="color:#0000ff">DishFlavorMapper</span> <span style="color:#770088">extends</span> <span style="color:#000000">BaseMapper</span><span style="color:#981a1a"><</span><span style="color:#000000">DishFlavor</span><span style="color:#981a1a">></span> { }</span></span>
3). 业务层接口 DishFlavorService
所属包: com.itheima.reggie.service
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">baomidou</span>.<span style="color:#000000">mybatisplus</span>.<span style="color:#000000">extension</span>.<span style="color:#000000">service</span>.<span style="color:#000000">IService</span>; <span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">itheima</span>.<span style="color:#000000">reggie</span>.<span style="color:#000000">entity</span>.<span style="color:#000000">DishFlavor</span>; <span style="color:#770088">public</span> <span style="color:#770088">interface</span> <span style="color:#0000ff">DishFlavorService</span> <span style="color:#770088">extends</span> <span style="color:#000000">IService</span><span style="color:#981a1a"><</span><span style="color:#000000">DishFlavor</span><span style="color:#981a1a">></span> { }</span></span>
4). 业务层实现类 DishFlavorServiceImpl
所属包: com.itheima.reggie.service.impl
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">baomidou</span>.<span style="color:#000000">mybatisplus</span>.<span style="color:#000000">extension</span>.<span style="color:#000000">service</span>.<span style="color:#000000">impl</span>.<span style="color:#000000">ServiceImpl</span>; <span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">itheima</span>.<span style="color:#000000">reggie</span>.<span style="color:#000000">entity</span>.<span style="color:#000000">DishFlavor</span>; <span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">itheima</span>.<span style="color:#000000">reggie</span>.<span style="color:#000000">mapper</span>.<span style="color:#000000">DishFlavorMapper</span>; <span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">itheima</span>.<span style="color:#000000">reggie</span>.<span style="color:#000000">service</span>.<span style="color:#000000">DishFlavorService</span>; <span style="color:#770088">import</span> <span style="color:#000000">org</span>.<span style="color:#000000">springframework</span>.<span style="color:#000000">stereotype</span>.<span style="color:#000000">Service</span>; <span style="color:#555555">@Service</span> <span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">DishFlavorServiceImpl</span> <span style="color:#770088">extends</span> <span style="color:#000000">ServiceImpl</span><span style="color:#981a1a"><</span><span style="color:#000000">DishFlavorMapper</span>,<span style="color:#000000">DishFlavor</span><span style="color:#981a1a">></span> <span style="color:#770088">implements</span> <span style="color:#000000">DishFlavorService</span> { }</span></span>
5). 控制层 DishController
菜品及菜品口味的相关操作,我们统一使用这一个controller即可。
所属包: com.itheima.reggie.controller
<span style="background-color:#f8f8f8"><span style="color:#333333">import com.itheima.reggie.service.DishFlavorService; import com.itheima.reggie.service.DishService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * 菜品管理 */ @RestController @RequestMapping("/dish") @Slf4j public class DishController { @Autowired private DishService dishService; @Autowired private DishFlavorService dishFlavorService; } </span></span>
2.4 前端页面分析
基本的准备工作我们已经做完了,那么接下来我们就需要来实现新增菜品功能,在开发代码之前,需要梳理一下新增菜品时前端页面和服务端的交互过程。
1). 点击新建菜品按钮, 访问页面(backend/page/food/add.html), 页面加载时发送ajax请求,请求服务端获取菜品分类数据并展示到下拉框中
2). 页面发送请求进行图片上传,请求服务端将图片保存到服务器(上传功能已实现)
3). 页面发送请求进行图片下载,将上传的图片进行回显(下载功能已实现)
4). 点击保存按钮,发送ajax请求,将菜品相关数据以json形式提交到服务端
页面代码:
开发新增菜品功能,其实就是在服务端编写代码去处理前端页面发送的这4次请求(上传、下载已实现)即可。经过上述的分析,我们还需要在服务端实现两块功能:
A. 菜品分类数据列表查询, 具体请求信息整理如下 :
请求 | 说明 |
请求方式 | GET |
请求路径 | /category/list |
请求参数 | ?type=1 |
B. 保存菜品信息, 具体请求信息整理如下 :
请求 | 说明 |
请求方式 | POST |
请求路径 | /dish |
请求参数 | json格式 |
下面呢,我们就需要根据这里分析的结果,分别来实现菜品分类列表的展示功能、保存菜品的功能 。
2.5 代码实现
2.5.1 菜品分类查询
在CategoryController中增加方法实现菜品分类查询,根据分类进行查询,并对查询的结果按照sort排序字段进行升序排序,如果sort相同,再按照修改时间倒序排序。
1.<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#aa5500">/**</span> <span style="color:#aa5500">* 根据条件查询分类数据</span> <span style="color:#aa5500">* @param category</span> <span style="color:#aa5500">* @return</span> <span style="color:#aa5500">*/</span> <span style="color:#555555">@GetMapping</span>(<span style="color:#aa1111">"/list"</span>) <span style="color:#770088">public</span> <span style="color:#000000">R</span><span style="color:#981a1a"><</span><span style="color:#000000">List</span><span style="color:#981a1a"><</span><span style="color:#000000">Category</span><span style="color:#981a1a">>></span> <span style="color:#0000ff">list</span>(<span style="color:#000000">Category</span> <span style="color:#000000">category</span>){ <span style="color:#aa5500">//条件构造器</span> <span style="color:#000000">LambdaQueryWrapper</span><span style="color:#981a1a"><</span><span style="color:#000000">Category</span><span style="color:#981a1a">></span> <span style="color:#000000">queryWrapper</span> <span style="color:#981a1a">=</span> <span style="color:#770088">new</span> <span style="color:#000000">LambdaQueryWrapper</span><span style="color:#981a1a"><></span>(); <span style="color:#aa5500">//添加条件</span> <span style="color:#000000">queryWrapper</span>.<span style="color:#000000">eq</span>(<span style="color:#000000">category</span>.<span style="color:#000000">getType</span>() <span style="color:#981a1a">!=</span> <span style="color:#221199">null</span>,<span style="color:#000000">Category</span>::<span style="color:#000000">getType</span>,<span style="color:#000000">category</span>.<span style="color:#000000">getType</span>()); <span style="color:#aa5500">//添加排序条件</span> <span style="color:#000000">queryWrapper</span>.<span style="color:#000000">orderByAsc</span>(<span style="color:#000000">Category</span>::<span style="color:#000000">getSort</span>).<span style="color:#000000">orderByDesc</span>(<span style="color:#000000">Category</span>::<span style="color:#000000">getUpdateTime</span>); <span style="color:#000000">List</span><span style="color:#981a1a"><</span><span style="color:#000000">Category</span><span style="color:#981a1a">></span> <span style="color:#000000">list</span> <span style="color:#981a1a">=</span> <span style="color:#000000">categoryService</span>.<span style="color:#000000">list</span>(<span style="color:#000000">queryWrapper</span>); <span style="color:#770088">return</span> <span style="color:#000000">R</span>.<span style="color:#000000">success</span>(<span style="color:#000000">list</span>); }</span></span>
2.5.2 保存菜品信息
在上述的分析中,我们可以看到在保存菜品时,页面传递过来的是json格式数据,格式如下:
<span style="background-color:#f8f8f8"><span style="color:#333333">{ <span style="color:#000000">"name"</span>:<span style="color:#aa1111">"佛跳墙"</span>, <span style="color:#000000">"price"</span>:<span style="color:#116644">88800</span>, <span style="color:#000000">"code"</span>:<span style="color:#aa1111">""</span>, <span style="color:#000000">"image"</span>:<span style="color:#aa1111">"da9e1c70-fc32-4781-9510-a1c4ccd2ff59.jpg"</span>, <span style="color:#000000">"description"</span>:<span style="color:#aa1111">"佛跳墙"</span>, <span style="color:#000000">"status"</span>:<span style="color:#116644">1</span>, <span style="color:#000000">"categoryId"</span>:<span style="color:#aa1111">"1397844357980663809"</span>, <span style="color:#000000">"flavors"</span>:[ { <span style="color:#000000">"name"</span>:<span style="color:#aa1111">"辣度"</span>, <span style="color:#000000">"value"</span>:<span style="color:#aa1111">"[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]"</span>, <span style="color:#000000">"showOption"</span>:<span style="color:#221199">false</span> }, { <span style="color:#000000">"name"</span>:<span style="color:#aa1111">"忌口"</span>, <span style="color:#000000">"value"</span>:<span style="color:#aa1111">"[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]"</span>, <span style="color:#000000">"showOption"</span>:<span style="color:#221199">false</span> } ] }</span></span>
在服务端我们应该如何来封装前端传递的数据呢,我们发现,如果使用菜品类Dish来封装,只能封装菜品的基本属性,flavors属性是无法封装的。那么这个时候,我们应该如何处理呢?
这个时候,我们需要自定义一个实体类,然后继承自 Dish,并对Dish的属性进行拓展,增加 flavors 集合属性(内部封装DishFlavor)。清楚了这一点之后,接下来就进行功能开发。
1). 导入 DishDto 实体类
封装页面传递的请求参数。
所属包: com.itheima.reggie.dto
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">itheima</span>.<span style="color:#000000">reggie</span>.<span style="color:#000000">entity</span>.<span style="color:#000000">Dish</span>; <span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">itheima</span>.<span style="color:#000000">reggie</span>.<span style="color:#000000">entity</span>.<span style="color:#000000">DishFlavor</span>; <span style="color:#770088">import</span> <span style="color:#000000">lombok</span>.<span style="color:#000000">Data</span>; <span style="color:#770088">import</span> <span style="color:#000000">java</span>.<span style="color:#000000">util</span>.<span style="color:#000000">ArrayList</span>; <span style="color:#770088">import</span> <span style="color:#000000">java</span>.<span style="color:#000000">util</span>.<span style="color:#000000">List</span>; <span style="color:#555555">@Data</span> <span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">DishDto</span> <span style="color:#770088">extends</span> <span style="color:#000000">Dish</span> { <span style="color:#770088">private</span> <span style="color:#000000">List</span><span style="color:#981a1a"><</span><span style="color:#000000">DishFlavor</span><span style="color:#981a1a">></span> <span style="color:#000000">flavors</span> <span style="color:#981a1a">=</span> <span style="color:#770088">new</span> <span style="color:#000000">ArrayList</span><span style="color:#981a1a"><></span>(); <span style="color:#770088">private</span> <span style="color:#008855">String</span> <span style="color:#000000">categoryName</span>; <span style="color:#770088">private</span> <span style="color:#008855">Integer</span> <span style="color:#000000">copies</span>; }</span></span>
拓展: 我们在做项目时,经常会涉及到各种类型的实体模型。基本包含以下几种
2). DishController定义方法新增菜品
在该Controller的方法中,不仅需要保存菜品的基本信息,还需要保存菜品的口味信息,需要操作两张表,所以我们需要在DishService接口中定义接口方法,在这个方法中需要保存上述的两部分数据。
1<span style="background-color:#f8f8f8"><span style="color:#333333">/** * 新增菜品 * @param dishDto * @return */ @PostMapping public R<String> save(@RequestBody DishDto dishDto){ log.info(dishDto.toString()); dishService.saveWithFlavor(dishDto); return R.success("新增菜品成功"); }</span></span>