苍穹外卖-菜品分页查询
3. 菜品分页查询
3.1 需求分析和设计
3.1.1 产品原型
系统中的菜品数据很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页的方式来展示列表数据。
菜品分页原型:
在菜品列表展示时,除了菜品的基本信息(名称、售价、售卖状态、最后操作时间)外,还有两个字段略微特殊,第一个是图片字段 ,我们从数据库查询出来的仅仅是图片的名字,图片要想在表格中回显展示出来,就需要下载这个图片。第二个是菜品分类,这里展示的是分类名称,而不是分类ID,此时我们就需要根据菜品的分类ID,去分类表中查询分类信息,然后在页面展示。
业务规则:
-
根据页码展示菜品信息
-
每页展示10条数据
-
分页查询时可以根据需要输入菜品名称、菜品分类、菜品状态进行查询
3.1.2 接口设计
根据上述原型图,设计出相应的接口。
3.2 代码开发
3.2.1 设计DTO类
根据菜品分页查询接口定义设计对应的DTO:
在sky-pojo模块中,已定义
package com.sky.dto;
import lombok.Data;
import java.io.Serializable;
@Data
public class DishPageQueryDTO implements Serializable {
private int page;
private int pageSize;
private String name;
private Integer categoryId; //分类id
private Integer status; //状态 0表示禁用 1表示启用
}
3.2.2 设计VO类
根据菜品分页查询接口定义设计对应的VO:
在sky-pojo模块中,已定义
package com.sky.vo;
import com.sky.entity.DishFlavor;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DishVO implements Serializable {
private Long id;
//菜品名称
private String name;
//菜品分类id
private Long categoryId;
//菜品价格
private BigDecimal price;
//图片
private String image;
//描述信息
private String description;
//0 停售 1 起售
private Integer status;
//更新时间
private LocalDateTime updateTime;
//分类名称
private String categoryName;
//菜品关联的口味
private List<DishFlavor> flavors = new ArrayList<>();
}
3.2.3 Controller层
根据接口定义创建DishController的page分页查询方法:
/**
* 菜品分页查询
*
* @param dishPageQueryDTO
* @return
*/
@GetMapping("/page")
@ApiOperation("菜品分页查询")
public Result<PageResult> page(DishPageQueryDTO dishPageQueryDTO) {
log.info("菜品分页查询:{}", dishPageQueryDTO);
PageResult pageResult = dishService.pageQuery(dishPageQueryDTO);//后绪步骤定义
return Result.success(pageResult);
}
3.2.4 Service层接口
在 DishService 中扩展分页查询方法:
/**
* 菜品分页查询
*
* @param dishPageQueryDTO
* @return
*/
PageResult pageQuery(DishPageQueryDTO dishPageQueryDTO);
3.2.5 Service层实现类
在 DishServiceImpl 中实现分页查询方法:
/**
* 菜品分页查询
*
* @param dishPageQueryDTO
* @return
*/
public PageResult pageQuery(DishPageQueryDTO dishPageQueryDTO) {
PageHelper.startPage(dishPageQueryDTO.getPage(), dishPageQueryDTO.getPageSize());
Page<DishVO> page = dishMapper.pageQuery(dishPageQueryDTO);//后绪步骤实现
return new PageResult(page.getTotal(), page.getResult());
}
3.2.6 Mapper层
在 DishMapper 接口中声明 pageQuery 方法:
/**
* 菜品分页查询
*
* @param dishPageQueryDTO
* @return
*/
Page<DishVO> pageQuery(DishPageQueryDTO dishPageQueryDTO);
在 DishMapper.xml 中编写SQL:
<select id="pageQuery" resultType="com.sky.vo.DishVO">
select d.* , c.name as categoryName from dish d left outer join category c on d.category_id = c.id
<where>
<if test="name != null">
and d.name like concat('%',#{name},'%')
</if>
<if test="categoryId != null">
and d.category_id = #{categoryId}
</if>
<if test="status != null">
and d.status = #{status}
</if>
</where>
order by d.create_time desc
</select>
1. 因为left join category表,即d表查全部,c表查部分,即c表有约束,约束的方式是用on关键字进行约束
2.因为d.*里有name属性,二者重合了,所以要给c.name取个别名,c.name as categoryName,否则mybatis底层无法完成自动映射。
3.
小结
分页查询菜品功能 1.把前端返回的数据封装成了DTO 2.把数据库查询返回的结果封装成了VO 3.分页查询 首先使用分页插件 然后进行查全部,因为涉及到了多表所以就用了了左外连接 把查到的结果封装成page<实体类> 最后封装PageResult返回 <!--查询所有菜品以及菜品所属分类 因为left join category表,即d表查全部,c表查部分,所以c表有约束,约束的方式是用on关键字进行约束--> <select id="findAll" resultType="com.sky.vo.DishVO"> select d.*,c.name as categoryName from dish d left join category c on d.category_id = c.id 。。。 </select> 小细节: 因为d.*里有name属性,二者重合了,所以要给c.name取个别名,c.name as categoryName,否则mybatis底层无法完成自动映射。