我最近和一个做毕设的学弟通了一个多小时电话,起因是他要用SpringBoot校园外卖平台完成系统设计并落地。他本人以前在学校跑腿群当过大半天群主,多少见过这类需求真实的狼狈样子,所以这个题目不是凭空捏造,是真有场景。聊完之后我只想说,校园外卖和面向全市场的美团、饿了么有很大不同,它有自己非常具体的业务约束,比如校区范围、取餐点、商家出餐能力、骑手身份的临时性。这些约束决定了你不需要把系统设计成一个大而全的外卖中台,做一个聚焦校园闭环的轻量平台反而真正能跑起来。
这篇内容主要面向三类人:正在做SpringBoot课程设计或毕业设计的同学,想入门Java后端完整项目但不想只照着教程敲代码的开发者,以及打算把这类项目作为“能力样板”放进简历里的人。整篇文章不会只贴代码,而是按我实际搞这个项目时的决策顺序,把业务边界、技术选型、数据表设计、接口鉴权、并发扣库存、订单自动取消、Docker部署和最后演示验收讲透。看完你能直接照着复现,也能理解每一步为什么这么定。
1. 上线前的业务拆解:校园外卖闭环里到底需要哪几个模块
做这种项目最怕一上来就开数据库建表。我见过太多把系统设计成“小美团”的例子,优惠券、会员、多商户入驻、客服工单全安排进去,结果下页面还没做完,整个项目已经失控。校园外卖的原始驱动场景其实非常朴素:用户在宿舍点餐,附近商家接单出餐,骑手或者商家自己送到楼下,用户取餐。把这三个环节跑通,平台就有价值了。
1.1 先理清三类角色和三段流程
系统核心角色我建议只保留三类:学生用户、商家、系统管理员。骑手可以做成一种特殊的身份,或者直接挂在商家侧管理,不要一开始就独立设计一套骑手抢单体系,否则你会陷入骑手端App、抢单算法这些无底洞。
业务闭环也相对固定,一共三段:
用户侧流程:用户选择校区内的商家 → 浏览菜品 → 加购物车 → 下单 → 支付 → 查看订单状态 → 确认收货。
商家侧流程:商家维护菜品和库存 → 接收新订单 → 接单 → 出餐 → 标记配送 → 订单完成。
管理侧流程:审核并管理商家 → 处理用户反馈 → 查看基础运营数据。
把这三段流程落到系统模块上你就知道,最核心的后端模块应该是:用户与权限、商家与菜品管理、购物车与订单、支付模拟(或接入)、订单状态流转。至于评价、收藏、会员成长体系,都属于锦上添花的扩展功能,放在二期完全可行。
1.2 第一版功能裁剪时的取舍思路
我帮学弟做第一版时,砍掉了很多看似必要的功能。第一,不做真实支付对接,而是做“模拟支付”加支付流水记录,因为个人开发者接入微信/支付宝支付有较高的资质门槛,而校园平台在课程设计和毕业设计阶段更看重流程完整性,不是支付牌照。第二,不做骑手独立App,配送状态由商家单方面更新,用户只读状态。第三,不做商家之间的平台级竞争流量分配,商家在地理上天然分散,不需要个性化推荐。
但你也要保留几个关键约束,否则演示的时候会显得特别业余:订单必须能体现完整的生命周期,从待支付到已支付、商家接单、配送中、完成、取消;菜品的库存要能被真实扣减,防止超卖;用户不能跨商家一起结算,因为外卖配送覆盖范围决定了一次订单只能来自一个商家。这些都属于“看着不炫但必须对”的业务规则,后面所有数据库设计和接口设计基本都围绕它们在转。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型取舍:SpringBoot 2.7.x + JDK8 的理由,以及哪些“热门组件”不该硬塞
我在定技术栈时做了一个很关键的决策:锁定SpringBoot 2.7.18 + JDK 8,而不是去追SpringBoot 3.x的最新版本。这不是因为我不了解新版本,而是我踩过太多“为了升级而升级”的坑,尤其是做校园项目和毕设,稳定性远大于新特性。
2.1 版本决策:为什么不推荐SpringBoot 3.x起步
SpringBoot 3.0之后强制要求JDK 17及以上,而目前很多学校的机房、个人电脑里装的是JDK 8,服务器配置也普遍有限,JDK 8+SpringBoot 2.7的组合恰恰是最成熟的黄金搭配。还有一个很实际的问题:很多培训机构资料、博客、甚至是AI代码补全默认生成的还是javax.*开头的包,而SpringBoot 3.x全面换成了jakarta.*,你一复制网上的代码就会因为包名不同直接编译失败,初学者根本不知道为什么。如果你刚学完JavaWeb,还在纠结环境问题,那SpringBoot 2.7.x会少给你添很多麻烦。
SpringBoot 2.7.18是2.x分支的最后一个版本,官方维护周期比较长,安全漏洞补丁覆盖也相对完整。这意味着你用它做项目,既不会像2.1那样老旧得有些三方组件不支持,也不会像3.x那样引入学习和迁移成本。SpringBoot版本偏高带来的尴尬我见过不少,有的同学因为版本太高,找遍全网都匹配不上一个老版本的MyBatis-Plus依赖,那段时间极其痛苦。把版本锁定下来,所有组件的版本选型也会顺利很多。
2.2 组件清单以及每一样解决什么问题
这个项目我选型的结果如下:
- JDK 1.8与SpringBoot 2.7.18,是后端基础和运行框架。
- MySQL 8.0,存核心业务数据,主要利用InnoDB事务保证订单和库存的一致性。
- MyBatis-Plus 3.5.x,做单表CRUD和分页查询非常快,能省下大量写Mapper XML的时间,但它只是辅助,不等于不用懂SQL。
- Redis 5.x或6.x,存登录验证码、用户Token以及部分热点菜品缓存。如果不想引入Redis,JWT无状态登录也可以不依赖Redis存Token,后面我会说明取舍。
- Spring Security或者轻量拦截器,做登录鉴权。我在这个中小型项目里选的是拦截器加JWT,不是Spring Security;原因后面有分析。
- Knife4j或Springfox,生成接口文档,方便联调时给前端同学看接口。如果团队里有前端协作,这个一定要配,不然对方会频繁问你“这个接口参数到底是啥”。
MySQL是核心事务型数据库,Redis是缓存和性能辅助,千万不要把订单数据也一股脑塞进Redis然后说“NoSQL快”。订单这种强事务、强状态字段的数据,放MySQL里更靠谱。Redis在这个阶段只承担辅助角色。还有JWT本身的特性就是无状态,Valid登录后下发Token,后续每次请求都带在Header里,鉴权时验签即可,所以不存Redis也能工作;一旦需要强制用户下线,就得把Token加到Redis黑名单。我在实际项目里用的是第二种变体,既能随时踢人,又比Spring Security配一堆过滤器链路简单。
2.3 哪些热门组件不该硬塞进校园外卖项目
最近经常有人在网上问SpringBoot怎么集成Flowable,似乎觉得工作流引擎会让外卖项目管理显得高级。但我劝你先想清楚业务:Flowable是BPMN工作流引擎,最擅长的是复杂审批流、任务调度、流程实例追踪。而外卖订单主流程本质上是一个事务性的状态流转,从支付到接单到配送再到完成,路径短且固定,你为它引入一条BPMN流程图完全是杀鸡用牛刀。Flowable的流程定义部署、流程实例创建、一类表格的数据查询,都会让你的项目维护成本直线上升。类似地,ActiveMQ、Kafka这类消息中间件,如果你的项目定位只是校园外卖,确实没有非用不可的场景。订单超时场景下延迟消息虽然是一种解法,但和定期扫描相比,带来的组件运维成本明显更高,这一点后面单独说。
我不反对引入看起来很炫的组件,但引入之前一定要想清楚它在业务里的明确位置。如果你的系统为了展示技术而硬塞Kafka,最可能的后果是面试官问你“这里的消费组和分区是怎么设计的”,你支支吾吾答不上来,反而暴露了知识盲区。如果一定要做亮点,SpringBoot自动装配原理、MyBatis-Plus插件机制、订单状态机设计,这些能在你不引入额外组件的情况下,成为真正的加分项。
3. 数据库主从拆分与订单状态流转的设计细节
随便找一张外卖订单来看,你会发现同一个订单里既有商品维度数据,又有订单整体维度数据。如果把菜品直接塞到订单表的一个字段里,以后统计、退款、对账都很难做。下面这张表是我项目初始版本的核心数据模型,我特别想讲清楚每张表为什么存在。
3.1 核心表清单和字段含义
| 表名 | 用途 | 需要注意的关键字段 |
|---|---|---|
| user | 学生用户和骑手用户 | role区分角色,默认0表示学生 |
| merchant | 入驻商家 | merchant_ |
