当前位置: 首页 > news >正文

苍穹外卖-day03-菜品分页查询模块学习笔记

苍穹外卖-day03-菜品分页查询模块学习笔记

【作者说:在这个模块中我了解到了Serializable 接口与implements 关键字等序列化的本质,这也是面试的高频考点,还有Mapper 层动态 SQL 开发,以及最后关于Apifox的使用流程,这是我以后调试接口的必要操作,这个app具有多功能的接口调试,极大地简化了调试接口的困难,我仍在逐步学习中,加油!!!】

一、序列化与 Serializable 接口(DTO/VO 必备基础)

核心定义

Serializable 接口:Java 的标记接口(接口内无任何方法),作用是给类打上「可序列化」标签,相当于给对象颁发 “运输许可证”。

implements 关键字:Java 关键字,作用是让类实现 / 认领这个接口,完成序列化权限的声明。

序列化本质就是把内存中 JVM 堆里的「活对象」(比如 DTO、VO、实体类),转换成可存储 / 传输的「静态字节流 / JSON 格式」;反序列化则是收到数据后,把字节流重新拼装成可用的 Java 对象--------就像你拼好的乐高机甲,只能在当前桌面(JVM 内存)展示,没法直接快递。序列化就是把机甲拆解成有序零件(字节流),方便运输 / 存入 Redis 缓存;反序列化就是收到零件后,重新拼回完整机甲(Java 对象)。而implements Serializable就是给机甲贴上「允许拆解运输」的标识,没有这个标识就无法完成拆解。


关键拓展(面试 / 开发高频考点)

1.为什么 DTO/VO 必须实现序列化?

苍穹外卖中,DTO 用于接收前端请求参数、VO 用于返回给前端响应数据,这些对象需要在网络中传输(前端↔后端),或存入 Redis
缓存(如登录态存储),必须通过序列化转换为字节流才能完成传输 / 存储。

2.序列化 ID(serialVersionUID)补充

建议手动指定private static final long serialVersionUID = 1L;,避免 JVM 自动生成的 ID
在类结构修改后发生变化,导致反序列化失败(比如修改 DTO 属性后,旧缓存数据无法反序列化)。 常见误区

3.不是所有类都需要序列化:仅用于后端内部逻辑处理、不参与网络传输 / 缓存的工具类,无需实现 Serializable 接口。


二、DTO 设计核心规范

核心要求
  • DTO(数据传输对象)中封装的属性,必须与需求设计的接口参数一一对应,做到字段名、类型完全匹配,避免参数接收失败。
  • DTO 与实体类的区分实体类:(Entity)对应数据库表结构,DTO 仅用于接口参数接收,不要直接用实体类作为入参(避免暴露数据库敏感字段,如 password、id 等)。
  • 参数校验增强可结合@NotNull、@Min等校验注解,对分页参数(page、pageSize)做合法性校验,避免非法参数导致 SQL 报错。

三、Mapper 层动态 SQL 开发(分页查询核心实现)

核心要点
  • DishMapper 中的 SQL 语句是动态 SQL,需要对每一个查询字段做非空判断,避免无效条件拼接导致查询异常。

  • 必须保证SQL 字段别名与 DTO/VO 属性名一一对应,否则 MyBatis 无法自动封装结果集。
    用concat函数实现动态模糊查询,用order by指定排序规则(菜品按create_time排序,保证最新数据优先展示)。

  • 动态 SQL 标签使用
    用标签做非空判断,标签自动处理多余的and/or,标签处理多条件互斥场景,避免手动拼接 SQL 的语法错误。

  • 分页插件集成(PageHelper)
    苍穹外卖中使用 PageHelper 分页插件,无需手动编写limit分页语句,只需在 Service 层调用PageHelper.startPage(page, pageSize)即可自动分页,简化开发。

  • 示例代码(DishMapper.xml 动态 SQL)

<?xml version="1.0"encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.sky.mapper.DishMapper"><!--菜品分页查询:支持名称模糊查询+分类+状态筛选,左联分类表获取分类名--><select id="page"resultType="com.sky.vo.DishVO"><!--d=dish菜品表 c=category分类表;起别名categoryName与DishVO字段对应-->select d.*,c.name as categoryName from dish d left join category c on d.category_id=c.id<!--where标签自动处理多余and,避免where1=1写法--><where><!--名称非空则拼接模糊查询,concat防SQL注入--><iftest="name != null and name != ''">and d.name likeconcat('%',#{name},'%')</if><!--分类ID非空则精确匹配,多表字段必须加表别名--><iftest="categoryId != null">and d.category_id=#{categoryId}</if><!--状态非空则精确匹配售卖状态--><iftest="status != null">and d.status=#{status}</if></where><!--分页必加排序,按创建时间倒序保证数据不乱-->order by d.create_time desc</select></mapper>

四、API Fox 接口调试全流程(实操步骤优化 + 拓展)

核心步骤
  1. 前置条件:保证 Spring Boot 项目正常启动(控制台打印Started SkyApplication),8080 端口正常监听。
  2. 获取 Token:调用「员工登录」接口,输入管理员账号密码,发送请求后从响应体中获取token字段。
  3. 全局配置 Token:点击右上角「环境管理」→「全局参数」,新增Header类型参数,key为token,value为刚获取的 Token,保存后所有接口自动携带该请求头(无需手动添加)。
  4. 测试分页接口:配置分页参数(page=1、pageSize=5),发送请求验证接口是否正常返回数据。
  5. 补充拓展(调试避坑 + 效率提升)
    5.1 Token 过期处理

苍穹外卖默认 Token 有效期为 2 小时,过期后需重新调用登录接口获取新
Token,更新全局参数即可;可在环境管理中配置「环境变量」,用{{token}}占位符,每次更新后全局生效,无需逐个接口修改。

5.2接口鉴权排查

若接口返回空数据 / 401
无权限,先检查「实际请求」标签中的请求头,确认token是否正常携带;部分接口虽标注「无需鉴权」,但后端代码仍做了登录校验,需手动添加Token。

5.3接口用例管理

可在 API Fox中为分页查询接口创建用例,保存不同参数(如page=1,pageSize=10、name="宫保"模糊查询),方便后续回归测试,提升调试效率。

5.4参数校验调试

可测试非法参数(如page=0、pageSize=-1),验证后端参数校验逻辑是否生效,保证接口健壮性。


五、高频面试考点拓展

  • 分页查询的性能优化

1.大数据量分页:避免limit 100000,10这种深分页,可通过「主键分页」(where id > 最后一条id limit 10)提升性能;
2.索引优化:为查询条件(name、category_id、status)、排序字段(create_time)建立联合索引,避免全表扫描;
3. 缓存优化:对高频访问的分页数据(如首页菜品列表),用 Redis 做缓存,减少数据库压力。

  • 动态 SQL 的优缺点

优点:灵活适配多条件查询,减少硬编码,提升代码可维护性;
缺点:复杂动态 SQL 可读性差,调试难度高,需注意 SQL注入风险(MyBatis 的#{} 会预编译,避免注入)。

  • 序列化的其他应用场景

除了网络传输,还用于:对象持久化(存入文件 / 数据库)、Redis 缓存对象、RMI 远程调用等。


六、笔记总结

本次菜品分页查询学习,我掌握了 DTO 序列化传输、MyBatis 动态 SQL 编写及多表联查要点,通过与实现灵活条件筛选,规范字段别名保证数据封装。在 APIFox 中完成项目启动、token 获取与全局配置、接口调试全流程,学会处理 token 过期与权限校验问题,实现前后端联调落地。

http://www.jsqmd.com/news/604650/

相关文章:

  • PSO-CNN-RF-ABKDE多变量时序预测 基于粒子群算法优化卷积神经网络结合随机森林结合自适应带宽核函数密度估计的多变量时序预测
  • Linux/Android文件系统架构深度剖析
  • Outfit完全掌握:从核心价值到实战应用的新手指南
  • Git LFS实战:如何高效上传大文件到GitHub(附常见问题排查指南)
  • Spring Boot 3.x强制JDK17?老项目迁移前必看的Java8兼容方案
  • HFSS 2023 R1实战:手把手教你从ADS优化到Wilkinson功分器建模(附完整模型文件)
  • 机械臂轨迹规划中的S型速度优化算法设计与实现
  • 假如说要设计一个多轮对话Agent,你会怎么设计?
  • 基于LabVIEW的纯软件信号发生器功能介绍
  • 变深声纳(VDS)收放系统技术情报报告
  • Maxwell永磁体磁场仿真:从表面强度到空间分布的全流程解析
  • 效率神器:用快马AI将antigravity彩蛋变为你的趣味开发效率工具
  • Python MCP服务器开发实战:从零搭建可扩展、可监控、可审计的企业级服务(附Gartner认证架构图)
  • Spring - 循环依赖
  • Agent可观测性工程:监控、追踪与告警的最佳实践
  • go-via(https://github.com/go-via/via)实现原理解读
  • 云凝结合计数器CNN粒子数浓度分析/python数据可视化
  • OpenVAS/GVM报错scan config error?三步排查法+国内源配置保姆级教程
  • 泛微E10二次开发前端通用方案:组件复写的应用场景与完整实操教程
  • 从Revit/BIM到Cesium:CesiumLab 4.0.7插件全流程打通,属性信息一个不丢
  • 新手福音:在wsl2中用快马生成你的第一个python命令行工具
  • 基于QT(C++)实现(界面)实现的五子棋游戏
  • 分布式共识:如何选出第一个leader?
  • 新手福音!5分钟手把手教你用JSON→C# Entities解决实体类生成难题
  • 告别量子调试:手把手教你正确使用QtConcurrent::run和QThreadPool执行类方法
  • MySQL数据库(基础语法篇
  • 【效率革命】Edge浏览器集成GPT:解锁智能搜索与内容创作新姿势
  • 双蒙皮声纳导流罩(Sonar Domes)技术情报报告
  • windows 10 powershell 分解大文件 分割大文件tar 包
  • Shell 脚本编程:从基础逻辑到生产级落地的核心指南