苍穹外卖——新增菜品模块学习笔记(含MyBatis XML映射格式)

张开发
2026/4/6 21:06:51 15 分钟阅读

分享文章

苍穹外卖——新增菜品模块学习笔记(含MyBatis XML映射格式)
苍穹外卖——新增菜品模块学习笔记含MyBatis XML映射格式小结【作者说在一段小模块的学习中我通常会以小见大在这篇笔记中我通过学习新增菜品了解到开发过程的先后顺序我认为这很重要对于一个没工作经历的在校学生来讲我们可以通过对这个项目一步步的学习来了解一个公司基本的开发逻辑主要是对三个层的了解(控制层Controller,业务层Service,数据访问层Mapper)。在目前的AI时代学习一些代码细节是完全没有必要的vibe coding的魅力就在于人来思考AI来执行。我将会继续更新之后的项目内容说说AI时代我的想法感谢点赞收藏关注我获取更多精彩内容】一、模块整体核心架构本次学习的新增菜品模块是苍穹外卖菜品管理核心功能模块整体采用前后端分离 SpringBoot 整合 MyBatis架构模式后端代码严格遵循控制层 - 业务层 - 数据访问层的分层开发思想各层分工明确、相互协作完成菜品数据从前端接收到数据库存储的全流程。整体涉及核心模块/文件分类控制层ControllerDishController 菜品专属控制类接收前端发送的新增菜品请求、处理请求参数CommonController 通用控制类封装文件上传功能支持图片、文件等通用上传不局限于菜品图片实现代码复用------传文件单独的类业务层Service------先写接口在写实现方式DishService 菜品业务接口定义新增菜品的业务方法规范DishServiceImpl 菜品业务实现类实现 DishService 接口编写新增菜品核心业务逻辑数据访问层Mapper-------映射两个接口MyBatis XML 格式DishMapper 、 DishFlavorMapper 接口数据访问接口定义数据库操作方法Mapper XML 映射文件存放于 resources/mapper 目录下采用 MyBatis XML 格式编写 SQL 语句实现 Java 代码与数据库的交互无需编写 JDBC 原生代码直接在 XML 中编写 SQL 完成数据库增删改查二、核心知识点梳理MyBatis 映射文件核心作用Mapper XML 映射文件是 MyBatis 的核心配置通过 XML 格式绑定对应的 Mapper 接口将 SQL 语句与 Java 方法解耦可以直接在 XML 中编写标准 SQL 语句实现后端 Java 代码对数据库的操作无需在 Java 类中拼接 SQL让代码更简洁、便于维护。核心注解Autowired本次学习重点掌握 Autowired 依赖注入注解其核心作用是无需手动 new 创建对象通过 Spring 框架自动完成对象的创建、装配实现不同类之间的依赖绑定与调用让两个互不相关的类可以直接调用对方的方法简化对象管理降低代码耦合度。例如在 Controller 中注入 Service 对象、在 ServiceImpl 中注入 Mapper 对象直接调用对应方法无需手动实例化。通用文件上传功能CommonController文件上传属于通用功能不单单服务于菜品图片上传因此单独抽取为 CommonController 实现代码复用。该模块主要处理前端上传的图片/文件完成文件接收、格式处理、存储等逻辑为新增菜品时的菜品图片上传提供接口支持。前端请求交互新增菜品前端页面主要传递菜品名称、菜品种类、菜品价格、菜品图片、菜品描述、菜品口味等参数通过接口请求发送到后端 DishController 后端分层处理后将数据最终存入数据库。三、新增菜品模块开发先后顺序-----由此掌握企业基础开发逻辑按照从下到上、逐层实现的开发逻辑配合Alt Enter快捷键快速补全代码具体顺序如下开发遵循从底层到上层的顺序因为上层代码需要调用下层代码必须先写被依赖的部分否则会报错。第一步设计数据库表并创建对应实体类先确定菜品、口味的数据表结构再编写与之对应的 Java 实体类作为整个模块的数据基础。​第二步开发数据访问层Mapper编写 Mapper 接口与 MyBatis XML 映射文件实现数据库增删改查操作。逻辑Service 层需要调用 Mapper 操作数据库因此 Mapper 必须优先开发。​第三步开发业务层Service编写 Service 接口与实现类注入 Mapper 并封装业务逻辑如同时保存菜品与口味。逻辑Controller 要调用 Service 处理业务所以 Service 在 Mapper 之后、Controller 之前。​第四步开发通用控制层CommonController实现文件/图片上传通用接口为菜品图片上传提供支持属于通用辅助功能。​第五步开发菜品控制层DishController定义接口地址接收前端请求调用 Service 完成新增逻辑并返回结果。逻辑Controller 是最上层入口依赖 Service因此放在最后开发四、核心调用逻辑前端发起新增菜品请求 → DishController 接收请求 → 调用 DishService 接口方法 → DishServiceImpl 执行业务逻辑、调用 Mapper 接口 → Mapper XML 执行 SQL 语句 → 数据写入数据库 → 逐层返回结果给前端完成新增菜品流程。五、MyBatis XML映射文件核心重点小结基础格式核心规则文件头部有固定声明是MyBatis XML映射文件的标识直接复用即可namespace是核心绑定项必须和对应Mapper接口的全限定类名完全一致实现接口与XML文件的绑定不同数据库操作对应专属 负责删除关键参数与语法要点parameterType 指定传入接口的参数类型保证参数传递匹配新增操作获取自增主键通过 useGeneratedKeys“true” 配合 keyProperty 属性拿到数据库自动生成的主键值参数传递使用 #{实体类属性名} 自动对应注入参数避免SQL注入批量操作标签实现批量数据插入/处理简化批量业务代码编写核心原则SQL语句与Java代码完全分离便于后期维护和SQL优化接口方法名与XML标签id保持一致一一对应遵循MyBatis规范编写保证数据库交互的稳定性4.关键代码展示//新增菜品MyBatis XML映射insert idinsertuseGeneratedKeystruekeyPropertyidinsert into dish(name,category_id,price,image,description,status,create_time,update_time,create_user,update_user)values(#{name},#{categoryId},#{price},#{image},#{description},#{status},#{createTime},#{updateTime},#{createUser},#{updateUser})/insert菜品口味映射与上述内容差不多就不做过多阐释。六、顺序展开新增菜品开发(仅以dish为例)1.设计数据库表并创建实体类设计数据库表创建实体类(仅以DTO为例)DTO后端接受前端数据的请求前端传回的数据的长度类型和格式都要与后端一一对应VO前端接受后端数据的请求后端要严格按照前端的数据格式进行“打包”通常为JSON格式DataBuilderNoArgsConstructorAllArgsConstructorpublicclassDishimplementsSerializable{privatestaticfinallongserialVersionUID1L;privateLongid;//菜品名称privateStringname;//菜品分类idprivateLongcategoryId;//菜品价格privateBigDecimalprice;//图片privateStringimage;//描述信息privateStringdescription;//0 停售 1 起售privateIntegerstatus;privateLocalDateTimecreateTime;privateLocalDateTimeupdateTime;privateLongcreateUser;privateLongupdateUser;//公共字段}2.MyBatis XML映射mapper接口文件----与mapper接口一一对应//新增菜品MyBatis XML映射insert idinsertuseGeneratedKeystruekeyPropertyidinsert into dish(name,category_id,price,image,description,status,create_time,update_time,create_user,update_user)values(#{name},#{categoryId},#{price},#{image},#{description},#{status},#{createTime},#{updateTime},#{createUser},#{updateUser})/insert3.开发业务层ServiceService接口publicinterfaceDishService{publicvoidsaveWithFlavor(DishDTOdishDTO);//新增菜品和对应的口味PageResultpage(DishPageQueryDTOdishPageQueryDTO);//菜品分页查询DishVOgetById(Longid);//根据id查询菜品voidupdate(DishDTOdishDTO);//修改菜品信息voiddelete(ListLongids);//批量删除菜品ListDishVOlist(LongcategoryId);//根据分类id查询菜品列表voidstartOrStop(Integerstatus,Longid);//菜品起售与停售ListDishVOlistWithFlavor(Dishdish);//条件查询菜品和口味}Service接口实现方法(主要与口味进行绑定)ServicepublicclassDishServiceImplimplementsDishService{ResourceprivateDishMapperdishMapper;ResourceprivateDishFlavorMapperdishFlavorMapper;/** * 新增菜品和对应的口味 * * param dishDTO 菜品DTO对象包含菜品基本信息和口味列表 */OverrideTransactional(rollbackForException.class)// 增加rollbackFor更严谨publicvoidsaveWithFlavor(DishDTOdishDTO){// 1. 创建Dish实体对象用于接收DTO数据并插入数据库DishdishnewDish();// 将DTO中的属性复制到实体对象中BeanUtils.copyProperties(dishDTO,dish);// 2. 插入菜品基本信息到dish表并自动生成主键iddishMapper.insert(dish);// 3. 处理口味数据ListDishFlavorflavorsdishDTO.getFlavors();if(flavors!null!flavors.isEmpty()){// 为每个口味设置对应的菜品idflavors.forEach(flavor-flavor.setDishId(dish.getId()));// 4. 批量插入口味信息到dish_flavor表dishFlavorMapper.insertBatch(flavors);}}}4.开发通用控制层CommonController----上传图片等文件publicclassCommonController{Autowired//自动装配代替new直接将AliOssUtil注入到当前类里可以在后面直接使用privateAliOssUtilaliOssUtil;PostMapping(/upload)ApiOperation(文件上传)publicResultStringupload(MultipartFilefile){log.info(文件上传);StringoriginalFilenamefile.getOriginalFilename();//截取后缀StringsuffixoriginalFilename.substring(originalFilename.lastIndexOf(.));StringobjectNameUUID.randomUUID().toString()suffix;//拼接文件名Stringurlnull;try{urlaliOssUtil.upload(file.getBytes(),objectName);}catch(IOExceptione){log.error(文件上传失败);returnResult.error(UPLOAD_FAILED);}returnResult.success(url);}}5.开发菜品控制层DishControllerpublicResultsave(RequestBodyDishDTOdishDTO){log.info(新增菜品);dishService.saveWithFlavor(dishDTO);cleanCache(dish_dishDTO.getCategoryId());returnResult.success();}七、新增菜品模块开发总结本次新增菜品模块开发完整落地了Spring BootMyBatis的分层开发范式严格遵循Controller→Service→Mapper的职责划分通过DTO/Entity/VO实现数据隔离与流转。核心依托 Transactional 保障菜品与口味表的事务一致性基于MyBatis映射文件完成SQL解耦复用通用文件上传能力实现图片存储。开发流程从表设计、实体创建到接口定义、业务实现、控制层开发闭环既掌握了分层架构思想也沉淀了可复用的业务开发模板为后续模块开发奠定了规范基础。

更多文章