ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于Spring Boot的超市仓库管理系统设计与开发实战

基于Spring Boot的超市仓库管理系统设计与开发实战 如果你的毕业设计选题还悬在半空超市仓库管理系统绝对是个不会出错的选项Java基础业务逻辑配上Spring Boot框架数据库用MySQL前端再用Vue或Bootstrap搭个页面既能体现业务闭环又能把增删改查玩出花样。这个题目看着普通但真正做完你会发现自己把Spring Boot、MyBatis-Plus、权限控制、库存计算、报表统计全过了一遍。我最近刚好完整实战了这个基于Spring Boot的超市仓库管理系统从需求梳理到部署交付走了一整轮顺手把源码、论文LW、部署说明和演示视频也整理齐了。下面就把整套思路、开发过程和踩过的坑摊开讲给正在做类似课设或毕设的同学一个能直接用的参考。1. 这个毕设项目到底在解决什么问题1.1 超市仓库管理的真实痛点很多同学拿到这个题目后第一反应是“不就是写个进销存吗”。结果动起手来才发现超市仓库和普通库存系统不太一样它有几个很实在的业务难点。首先是商品种类多、单位杂一瓶水和一台电饭煲的体积、计量单位、补货周期完全不同系统里不能只存“数量”还得能区分进货单位、销售单位和库存单位之间怎么换算。其次是库存变动频繁每天有几十个供应商来送货也有几百笔销售出库任何一笔漏记或重复记账月末盘点就会对不上账。第三个痛点是预警机制。超市里生鲜、酸奶这类商品是有保质期的临期商品如果不提醒直接变成损耗。五金百货类的商品则容易积压资金被压在仓库里。因此系统不能只做“有记录”还得能做“快到保质期提醒”和“低库存预警”这就把简单管理系统提升到了有业务价值的程度。最后是权限问题。仓库管理员、采购员、超市店长看到的数据范围不同。仓管只管出入库操作采购要能看到供应商和订单状态店长则需要看库存总览和库存成本。一套系统如果搞不定权限区分答辩时很容易被老师问住不同角色的数据边界在哪里你怎么保证的。1.2 为什么选Spring Boot而不是SSH或SSM前些年毕设里流行SSHSpring Struts Hibernate和SSMSpring SpringMVC MyBatis现在再提出这套方案除了怀旧没有任何优势。Spring Boot最大的价值是“约定优于配置”它把以前需要写一大堆XML的配置过程压缩成几个注解内嵌Tomcat打成一个Jar包就能跑。对毕设来说省下来的时间应该用在业务逻辑上而不是耗在折腾配置文件上。另外Spring Boot生态对新手更友好。我见过太多同学花两周时间搭SSM环境最后死在jar包冲突上连登录页面都没写出来。换成Spring Boot之后用Spring Initializr生成工程依赖一加启动类一写项目就能跑起来。加上它内置了Actuator、测试框架、参数校验这些实用工具答辩时还能拿出“统一异常处理”“接口数据校验”这样的加分项。还有个现实原因现在的企业招聘和后端岗位JD里Spring Boot几乎是必备关键词。你拿一个Spring Boot项目去写简历面试官至少愿意多问两句你拿一个十年前结构的SSH项目很多面试官会直接在心里给你扣分。所以选型这一步不只是在选技术也是在给自己的就业铺路。1.3 这类毕设的核心评分点在哪很多同学以为毕设评分看的是代码量其实老师和答辩评委更看重“需求分析是否清楚、模块划分是否合理、数据设计是否规范、有没有真正跑起来”。超市仓库管理系统能成为经典毕设题就是因为业务场景够具体不需要答辩人编造需求只需要把超市仓库里“入库—出库—库存—统计”这条线理清楚。评分点一般集中在四块。一块是数据库设计表之间是外键关联还是逻辑关联索引有没有加冗余字段设计得合不合理一块是业务逻辑商品入库时库存怎么变、出库时库存不足怎么拦截、退货时又是怎么处理一块是前端界面页面是否完整操作是否顺手有没有对输入做校验最后一块是部署演示能不能在干净环境里跑起来录制的演示视频有没有把核心功能讲清楚。明白这些评分点之后你就知道该把时间花在哪了不要沉迷于写花哨的CSS动画先保证数据库表和核心业务代码能自圆其说再考虑锦上添花的功能。2. 系统设计与技术选型深入拆解2.1 整体功能模块从入库到出库的闭环我做的这套系统功能模块可以分成六个大的部分系统登录与权限管理、商品信息管理、供应商管理、入库管理、出库管理、库存与统计报表。听起来不多但每个模块下面都有好几层细节。登录和权限管理我用了Spring Security JWT前端登录后拿到Token之后每次请求都带上Token后端通过拦截器校验。这么做的好处是前端和后端可以完全分离开发时不用互相等。权限上我设计了三个角色管理员、仓库操作员、普通员工。管理员能配置基础数据和查看所有报表仓库操作员只能操作出入库单普通员工只能看商品信息和库存查询。这样一区分后续的接口设计也跟着清晰了。商品信息管理是整个系统的地基。每一件商品都有分类、条码、名称、规格、单位、进价、售价、预警库存、保质期、商品图片等字段。这里要注意商品条码建议用唯一索引超市实际运营中条码就是商品的身份证重复就乱套。分类表单独建一张商品表用外键关联分类避免商品表里存一堆中文分类名造成冗余。供应商管理模块相对简单就是供应商基本信息加联系人、电话、地址、供货类别。但别小看它入库单要关联供应商统计报表里也能按供应商汇总进货金额所以表结构不能漏了“供应商编码”和“信用账期”这些字段。入库管理模块里我拆成了“入库单”和“入库明细”两步。入库单记录哪家供应商、哪个仓库、哪个人操作的、单据编号、入库日期、总金额入库明细记录每件商品入库数量、单价、生产日期、过期日期。为什么要拆主表和明细表因为一张入库单会包含多种商品如果全部塞在一张表里字段会有大量重复后期统计和修改都会很难受。出库管理模块同理出库单记录出库去向是销售出库还是其他出库、操作员、出库日期出库明细记录商品出库数量与所对应的入库批次。这里我额外做了一个批次记录后面讲库存计算时会详细说这也是系统比普通CRUD练习高级的地方。库存与报表模块是整个系统的“输出端”。库存表实时汇总每个商品的当前库存量、库存金额、预警状态报表模块提供按日期的出入库流水表、按商品的进出汇总、按分类的库存分布。答辩时打开这几个报表页面老师能一眼看出系统的业务完整性。2.2 数据库表设计核心表与关联关系数据库设计是这类系统最容易翻车的环节很多同学的库表就像临时拼出来的缺外键、少索引、类型不对导致后期查询越写越痛苦。我这里把核心表结构完整列出来给你直接参考。首先是用户表字段包括id、username、passwordBCrypt加密后的密文、real_name、role、phone、status、create_time。密码千万不要明文保存答辩时被问到安全问题你至少能说出“用BCrypt加密存储”。然后是角色因为角色比较少我没有单独建角色表和权限表直接用字符串字段区分简单够用但如果想做得更规范建议建角色表和用户-角色关联表。商品分类表字段比较简单id、category_name、parent_id、sort_order。这里我加了parent_id是为了支持二级分类比如“食品”下面可以挂“饮料”“零食”“粮油”。商品表核心字段是id、category_id、bar_code、name、specification、unit、purchase_price、sale_price、low_stock、current_stock、expiry_date、status。其中current_stock是冗余字段一般不建议频繁更新但这里考虑到超市场景需要实时显示库存我选择在出入库事务提交时同步更新它配合后续的可选“库存流水表”做审计。供应商表是id、supplier_code、name、contact_person、phone、address、category_desc、status。入库主表和入库明细表要特别注意入库主表(inbound_order)有id、order_no、supplier_id、warehouse_id、operator_id、total_amount、status、create_time入库明细表(inbound_order_item)有id、inbound_order_id、product_id、quantity、purchase_price、product_date、expire_date、batch_no。批次号怎么生成我用的是“商品ID 入库日期 随机数”组合这样同一商品多次入库能被区分开过期预警也靠这个批次。出库表结构和入库对称outbound_order(id, order_no, type, operator_id, remark, create_time)和outbound_order_item(id, outbound_order_id, product_id, quantity, batch_no)。注意这里的batch_no它负责把出库和前面对应的入库批次关联起来这样库存才能按批次扣减临期商品可以优先出库。如果你不做批次管理那报表和预警就会缺失很多信息。最后是库存表和流水表。库存表可以直接用商品表里的current_stock字段但更严谨的做法是再建一张inventory(id, product_id, warehouse_id, quantity, updated_time)为将来多仓库扩展留余地。流水表inventory_record则记录每次入库出库前后的库存变化字段为id、product_id、change_type(IN/OUT)、change_quantity、before_quantity、after_quantity、related_order_no、create_time。流水表是事后追溯的依据老师如果问“库存数据错了怎么办”你就可以拿流水表来说可以逐条回放。这里顺带分享一个MyBatis-Plus的实用技巧很多同学还在手写SQL建表其实可以先用实体类定义好Java字段再用MyBatis-Plus代码生成器或自动建表能力直接根据实体类生成创建表的SQL语句。不过自动生成的表结构有时字段注释、索引设计不够精细建议生成后再手工补一下注释和索引。我实际开发中是把表的SQL写好后放进项目resources/db目录配合部署说明让使用方执行一次初始化脚本这样比完全交给工具更可控。2.3 后端架构Controller-Service-Mapper三层项目结构我用了最标准的Controller-Service-Mapper三层用Maven管理按功能分包。controller包接收前端HTTP请求给出REST接口service包写业务逻辑处理事务mapper包负责和数据库交互用MyBatis-Plus承担单表CRUD复杂查询用XML自定义SQL。Controller层的代码尽量“轻薄”只做参数接受、简单校验、调用Service并返回统一结果对象。我定义了一个Result类里面有code、message和data三个字段成功返回code200业务异常返回业务码。所有Controller方法都返回Result前端拿到结果后再判断是否提示错误。这样比直接返回一个JSON里乱套的Map要规范得多。Service层是重点所有业务规则都在这一层。比如入库时不仅要往inbound_order和inbound_order_item表插入数据还要同步更新商品表的current_stock再记一条库存流水。这两个操作必须放在同一个事务里否则就可能出现“单据存了库存没变”或者反过来。Spring里直接在Service方法上加上Transactional注解事务就生效了。这里特别提醒一下事务一定要加在public方法上并且不能同类内部调用否则事务会失效。我一开始就踩过这个坑入库明细插入成功库存没更新数据库里数据对不上排查半天才发现是同类中另一个方法直接调用了带事务注解的方法。Mapper层用MyBatis-Plus是真的省事。单表CRUD完全不用写SQL直接继承BaseMapper 就行。分页查询用MyBatis-Plus的分页插件设置Page对象后查询结果里直接带total和records。复杂一点的联表查询比如“查询入库单明细并带上商品名称和供应商名称”就直接在XML里写SQL用JOIN关联避免内存拼装数据。注意尽量别在循环里查数据库比如遍历入库明细时逐个去查商品信息效率低且很容易出N1问题。正确做法是先查出所有商品ID用IN查询一次性把商品信息拿回来再组装。2.4 前端与交互先定页面再定接口前端我选用Vue 2 Element UI搭建了一个后台管理页面。选择Element UI的原因很简单表格、表单、弹窗、日期选择器都是现成的做毕设能省大量CSS时间。如果不想用Vue直接用Bootstrapthymeleaf模板也不是不行但前后端分离的开发体验会差不少接口测试和部署维护也没有那么顺畅。前端页面规划按业务模块走登录页、首页工作台显示今日入库单数、出库单数、预警商品数、商品管理页表格搜索、新增编辑弹窗、删除确认、入库管理页入库单列表、新增入库单、入库单详情、出库管理页、库存查询页、供应商管理页、统计报表页。在开发接口之前我会先给后端定好一套API文档。比如商品管理接口有“GET /api/product/list”“POST /api/product”“PUT /api/product”“DELETE /api/product/{id}”入库接口有“GET /api/inbound/page”“POST /api/inbound/order”“GET /api/inbound/order/{id}”。前端模块不需要接口时可以先按约定好的JSON格式mock数据后端开发完成后再对接。这样两个人各自开发互不干扰就算一个人全干也能明显减少返工时间。推荐用Apifox或者Postman做接口测试写好的接口可以直接生成在线文档录演示视频时也能先把接口验证一遍。我不建议前端开发时把整个项目打成War包扔进Tomcat运行前后端分离状态下直接两个端口跑前端8081、后端8080配好跨域配置调试效率会高很多。3. 实战开发关键模块从零实现3.1 搭建工程和依赖配置我用的Java版本是1.8Spring Boot版本选了2.7.x配合MyBatis-Plus 3.5.x。这套组合目前最稳定参考教材和网上的资料也都对得上不会出现“注解包路径变了”的坑。很多同学一上来就选Spring Boot 3.x结果发现javax.servlet变成了jakarta.servlet满屏红叉又不知所措。这里说句实在话做毕设选稳定版本比追新版本更重要。pom.xml里核心依赖就这么几个spring-boot-starter-web、spring-boot-starter-validation、mybatis-plus-boot-starter、mysql-connector-java、lombok、jwt、spring-security-crypto。完整写出来有点多但都很好找。配置application.yml时主要配置数据源、MyBatis-Plus逻辑删除和分页插件、JWT密钥和过期时间。这里贴一个最核心的数据源配置server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/supermarket_wms?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 你的密码 mybatis-plus: configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0注意url里的characterEncoding一定要设置成utf8否则插入中文会变成问号。以前常踩的坑是把MySQL连接驱动写成老旧的com.mysql.jdbc.Driver在MySQL 8以上会直接报错现在统一用com.mysql.cj.jdbc.Driver。3.2 商品管理模块的实现细节商品管理是最基础的模块但做起来很讲究。商品Controller提供了分页查询、新增、修改、删除和详情五个接口。新增和修改的入参是ProductForm对象带一些校验注解比如商品名称不能为空、进价售价必须大于0等。Controller里直接加上Validated参数不对时会被全局异常处理器统一拦截返回友好的提示信息。商品分页查询的前端展示需要分类名称但product表里只有category_id所以查询要走JOIN。我的ProductMapper中定义了一个ProductPageVO查询XML里的SQL大概长这样select idselectProductPage resultTypecom.demo.vo.ProductVO SELECT p.id, p.bar_code, p.name, p.specification, p.unit, p.purchase_price, p.sale_price, p.current_stock, p.low_stock, p.expiry_date, c.category_name FROM product p LEFT JOIN category c ON p.category_id c.id where if testname ! null and name ! AND p.name LIKE CONCAT(%, #{name}, %) /if if testcategoryId ! null AND p.category_id #{categoryId} /if /where ORDER BY p.id DESC /select分页参数我直接在Service层构建一个Page 查询后把records转成VO返回。为什么不用实体直接返回因为实体里带了一些不该暴露的字段比如逻辑删除标记而且多一条分类名称字段前端能少做一次转换。新增商品的逻辑要注意两点。第一条码重复时应该拦截我会在插入前根据barCode查一下商品表存在就抛出业务异常“该条码已存在”。第二新增商品时current_stock初始为0库存只能由入库单产生不能在商品编辑页直接改库存否则库存变动就没有流水可查。这是一个容易犯的逻辑漏洞很多系统把“修改库存”和“入库单”混在一起最终数据就对不上了。3.3 入库/出库单带来的库存变动逻辑入库单是整张系统的业务核心。我设计的入库流程是前端填好入库单基本信息再通过弹窗逐行添加入库明细提交时一次性把整张入库单数据以JSON格式发送到后端。Controller接收的是一个InboundOrderDTO里面包含供应商ID、操作员ID和明细列表。Service层要做的事很多我拆成四步第一步校验明细数据。每条明细的商品ID不能为空入库数量要大于0单价要大于等于0。如果有过期日期还要校验过期日期不能早于生产日期。第二步生成入库单号。我用的格式是RKyyyyMMdd四位随机数比如RK202405180023。用一个全局工具生成后用“单号是否存在”做唯一校验防止并发重复。第三步保存主表和明细表并更新库存。这一步我会同时遍历所有明细逐个更新product表的current_stock再插入inventory_record流水。因为是同一个事务任何一个明细失败都会整体回滚。第四步汇总入库单总金额并回填到主表的total_amount入库单状态设为已入库。出库的逻辑跟入库相反但多了一个“库存足够吗”的校验。我判断的逻辑是根据出库明细里的商品ID查出当前库存如果current_stock小于出库数量直接抛异常“商品XX库存不足”同时把该商品的可用库存也返回给前端页面。这里就体现出批次的作用了如果按批次扣减我需要先查这个商品下的批次表按“先过期先出”的顺序扣减这样能有效降低超市损耗。这里贴一个我实际写的库存扣减代码核心片段重要就是加锁防超卖。虽然毕设里并发量不高但面试时被问到怎么做防超卖你可以说有意识地用过悲观锁或乐观锁。我选择的是在更新库存时加上“库存大于待扣数”的SQL判断配合事务回滚Transactional(rollbackFor Exception.class) public void outboundStock(OutboundOrderDTO dto) { for (OutboundItemDTO item : dto.getItems()) { Long productId item.getProductId(); Integer quantity item.getQuantity(); // 使用条件更新防止超卖 int rows productMapper.decreaseStock(productId, quantity); if (rows 0) { throw new BusinessException(商品ID productId 库存不足); } recordService.writeRecord(productId, OUT, quantity); } }Mapper里的decreaseStock大概是这样update iddecreaseStock UPDATE product SET current_stock current_stock - #{quantity} WHERE id #{productId} AND current_stock gt; #{quantity} /update这里“受影响行数为0”就代表库存不足由此抛出异常事务回滚不会出现负数库存。这种做法在并发下单场景里依然有效也是面试时能聊几句的亮点。3.4 库存预警功能怎么触发的库存预警一般分两种数量预警和保质期预警。数量预警很简单查询时把current_stock小于等于low_stock的商品标红或者在首页统计数字里显示预警数量。我实现的时候用了定时任务每十分钟扫描一次所有商品把低库存的商品生成一条预警记录。这个不是必须但加上会让答辩时展示效果更好。保质期预警相对复杂依赖的是商品或入库批次里的expire_date。我按日期差值来区分状态剩余天数大于30天是正常小于等于30天且大于7天是“即将到期”小于等于7天是“临期”。在商品列表和入库批次列表里直接用标签展示这些状态。更实用的做法是在首页展示最近7天内到期商品清单让仓管集中处理。为了让预警更有价值我还加了一个简单的“建议补货数”计算如果当前库存低于预警库存差值就是建议补货量。这个计算逻辑不复杂在Service层一个循环就能搞定。但注意别把“预警库存”和“安全库存”搞混预警库存是触发提醒的阈值安全库存还可以考虑日均销量。简化版用预警库存就够了答辩时你可以补充说明真实系统里会结合日均销量和采购周期来计算优化值。4. 部署与交付论文、演示视频和答辩准备4.1 本地打包与运行开发完项目后打包部署是很多人第一次翻车的地方。我建议使用Maven的package命令打成Jar包确保本地Java环境正确然后在命令行执行java -jar supermarket-wms.jar。如果在服务器上部署用宝塔面板加Docker跑一个MySQL和Spring Boot容器能少踩很多环境坑。打包前有几点必须检查application.yml里数据库密码是否配好前端是否已经构建并放到了后端静态资源目录。如果前后端分离前端构建出的dist目录需要拷贝到Spring Boot项目的src/main/resources/static下面。这样打出来的Jar包才能同时提供接口和页面别人拿过去一条命令就能访问。如果不做这一步别人还要另外启动前端Node服务部署说明就会复杂很多。数据库初始化脚本要放到项目根目录的db文件夹下命名类似supermarket_wms.sql内容包括建库、建表、插入初始数据。初始数据至少要有管理员账号、几个分类、几种商品和供应商方便验收时直接看到页面效果。脚本要能重复执行所以建表语句里加上DROP TABLE IF EXISTS插入语句要有固定的主键避免用自增ID造成数据错乱。4.2 LW论文写作的套路和注意事项LW其实就是毕业设计论文这套系统的论文写作有固定套路别自己瞎编。我建议的结构是第一章绪论写研究背景、意义、现状、论文组织结构第二章相关技术介绍Spring Boot、MyBatis-Plus、MySQL、Vue都要介绍一遍这一章比较好扩字数第三章系统分析包含可行性分析、需求分析、用例图、功能模块图第四章系统设计包含架构设计、功能模块设计、数据库设计E-R图、表结构第五章系统实现把核心模块的页面截图和代码片段贴进去配上功能描述第六章系统测试写测试环境、功能测试用例、测试结果最后是总结与展望。论文里最容易忽视的是图表规范。每个模块都要有自己的功能结构图数据库设计必须有E-R图用例图要能表达不同角色的操作权限。如果你自己不擅长画图可以用draw.io或ProcessOn画完之后嵌入Word文档。注意图表里的中文不要出现乱码导出PNG时分辨率要够高。写完初稿之后建议用学校给的查重系统查一遍重复率控制在20%以下。写技术介绍部分时不能大段复制网上文章要用自己的话重新组织。代码片段一般不计入查重但也要把变量名和注释改得有自己的风格。论文格式上问清楚指导老师用哪个模板尤其是页眉页脚、目录格式和参考文献的GB/T 7714标准这些细节最容易扣分。4.3 演示视频录制技巧演示视频是为了让评阅老师远程也能了解你的系统。录制时间控制在五分钟到八分钟之间太短讲不清太长没人有耐心看完。录制工具我用的OBS Studio免费且支持1080P高清录制也可以用Screen Recorder这类轻量工具。录制前把数据库重置成初始状态再把缩放比例调到合适的窗口大小避免录出来的画面字太小。视频脚本建议按“登录—首页—商品管理—入库—出库—库存预警—权限切换—报表”的顺序走。每个页面停留时间不要太长重点操作配一两句解说。录制前把鼠标移动练熟尽量不要录到中途改代码或刷新数据库。出错没关系停顿两秒再继续后期用剪辑软件把啰嗦片段剪掉。输出的时候选MP4格式分辨率为1920x1080文件体积一般不会超过200MB。4.4 答辩被问得最多的问题怎么答答辩环节是很多人的心理关其实老师问来问去就那么几类问题提前准备好就能稳住。第一个必问“你这个系统的核心业务流程是什么”要把“入库单生成—库存增加—出库单生成—库存扣减—库存预警—报表统计”这条链路用一分钟讲清楚最好边说边指向系统页面。第二个问题“数据库表之间是怎么关联的”准备好关系说明比如商品表和分类表是多对一入库单和入库明细是一对多库存流水和商品是多对一。回答时直接说主外键关系和删除策略别含糊。第三个问题“你的事务是怎么控制的”可以说入库单插表和库存更新放在同一事务出库扣减库存用条件更新防止超卖。再提一下事务的隔离级别是默认的数据库级别背书一下Spring的Transactional原理。第四个问题“这个系统有什么可以改进的地方”别急着说没有。可以说以后可以扩展多仓库管理、增加采购审批流程、接入扫码枪、用Redis缓存热门商品库存以及增加消息队列做库存变动通知。这样既展示了你的思考深度又不会给自己挖坑。5. 常见问题与排查技巧实录5.1 Maven依赖冲突与版本问题这类Spring Boot项目最常见的报错就是NoSuchMethodError、ClassNotFoundException或者启动时BeanCreationException十有八九是jar包版本冲突。建议所有依赖版本都用父工程Spring Boot BOM里的默认版本不要手动每个jar都填版本号。比如Spring Boot 2.7.x下引入MyBatis-Plus时用mybatis-plus-boot-starter 3.5.3它依赖的mybatis-spring版本和Spring Boot兼容。排查依赖冲突可以用IDEA的Maven Helper插件打开dependency analyzer搜索出冲突的高亮依赖右键exclude掉不需要的传递依赖。我在项目里遇到过lombok版本和Spring Boot搭配不当导致编译报错用Maven Helper排除后重装依赖就好了。记住一个原则依赖越少越好能不加的乱七八糟工具包都不要加。5.2 Spring Boot版本太高导致的兼容问题做这个毕设时我一开始图新鲜用了Spring Boot 3.2.x结果MyBatis-Plus官方文档里的很多示例代码全都跑不通。后来发现问题出在javax到jakarta的迁移上MyBatis-Plus老版本根本识别不了新的包名。更麻烦的是Spring Boot 3.x要求Java 17而很多学校的个人电脑还是Java 8部署环境不匹配演示时容易现场翻车。我的建议是如果你只是为了完成毕业设计老老实实用Spring Boot 2.7.x Java 8。如果确实想挑战新版本也要先确认MyBatis-Plus选了3.5.3以上并支持jakarta的版本同时本地JDK版本正确。记住稳定压倒一切技术新不新不是答辩老师给你的主要评分依据跑得动才是。5.3 数据库连接和字符集问题数据库连接失败或中文乱码是毕设演示现场的头号事故。先说连接失败确认MySQL服务有没有启动3306端口有没有被占用创建数据库时字符集选择utf8mb4连接串里加上serverTimezoneAsia/Shanghai。如果是云服务器部署记得在宝塔或云安全组里放行3306端口但不要把数据库账号设成太简单的密码毕竟这也是安全常识。中文乱码通常发生在创建表时没有指定字符集。一个有效排查方法是在Navicat里查看表数据如果数据库里的中文正常但页面显示乱码那就是后端配置或前端页面编码问题把前端HTML的charset设置成UTF-8并检查接口返回的Content-Type。我建议在建表语句里统一加上ENGINEInnoDB DEFAULT CHARSETutf8mb4省去很多麻烦。5.4 答辩时被问得最多的问题怎么答最后再补几个实用小技巧都是我在实际运维中总结出来的。第一演示前把浏览器的开发者工具F12关掉不要让它占屏幕。第二演示时先刷新一下首页如果数据库没初始化很多同学打开的就是报错页面印象瞬间下滑。第三如果中途出现接口报错别慌微信截图或者保留现场可以先说“这个问题我在本地环境已经验证过可能是当前网络或数据库状态问题”然后快速检查后台日志。另外演示视频千万不要在答辩前一晚才录最好给项目文档、数据库脚本、部署说明、视频文件都放在同一个压缩包里命名规范一点不要叫“新建文件夹.zip”。老师给你的代码审核意见往往就几项能跑通、有基本业务逻辑、表设计合理、论文格式规范满足这些之后项目细节上的小瑕疵都可以通过沟通圆过去。我做这个项目的最大体会是毕设不是要你发明一个惊天动地的系统而是要训练你完成一个真实业务需求的全流程能力。超市仓库管理系统这个题目虽然经典但只要你把核心业务逻辑吃透、把每个报错都解决掉、把演示脚本过几遍它依然能成为你简历里的一个扎实项目。最后分享一个小技巧把项目的每个模块在Git里分好提交记录写论文时直接看commit记录就知道每段时间在干什么答辩证也不会逻辑混乱。祝你的毕设一次通过。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进