Spring Boot: 综合实战:OrderFlow 项目设计
最后更新:2026-08-26
项目设计是开发的蓝图——需求定方向,选型定技术,设计定架构,磨刀不误砍柴工。
1. 你将学到
- Charlie 提出业务需求:用户管理 / 商品管理 / 订单管理 / 支付管理四大模块
- 技术选型决策:WebMVC vs WebFlux、Session vs JWT、本地缓存 vs Redis
- 数据库 ER 图设计:User / Product / Order / OrderItem / Payment 表结构
- RESTful API 规约设计:URI 命名 / 版本控制 / 分页排序 / HATEOAS
- Alice 制定开发计划与模块分工
2. 一个产品经理的真实故事
(1) 痛点:需求到代码的鸿沟
Charlie 拿着一份模糊的需求文档找 Alice:"我们需要一个电商订单管理系统。"Alice 问:有哪些功能?用户分几种角色?商品有哪些属性?订单和支付怎么关联?Charlie 说不清楚,Alice 只能凭经验猜,结果开发了 2 周后 Charlie 说"这不是我要的"。
(2) 系统设计的解法
先设计再开发——需求分析 → 技术选型 → 数据库设计 → API 规约,每步与 Charlie 确认:
graph TD
A["Requirements<br/>Analysis"] --> B["Tech Stack<br/>Selection"]
B --> C["Database<br/>Design"]
C --> D["API<br/>Specification"]
D --> E["Development<br/>Plan"]
(3) 收益
Alice 和 Charlie 花 2 天完成系统设计后,开发方向明确,3 周内交付了符合预期的 MVP。Charlie 说"第一次开发出来就是我要的"。
3. 需求分析
(1) 四大模块
| 模块 | 核心功能 | 用户角色 |
|---|---|---|
| 用户管理 | 注册、登录、个人信息、角色管理 | ALL |
| 商品管理 | CRUD、分类、搜索、库存管理 | ADMIN |
| 订单管理 | 下单、查询、取消、超时自动取消 | CUSTOMER / ADMIN |
| 支付管理 | 发起支付、回调处理、退款 | CUSTOMER / ADMIN |
(2) 角色权限矩阵
| 功能 | CUSTOMER | ADMIN |
|---|---|---|
| 注册 / 登录 | ✅ | ✅ |
| 浏览商品 | ✅ | ✅ |
| 搜索商品 | ✅ | ✅ |
| 创建 / 管理商品 | ❌ | ✅ |
| 下单 | ✅ | ✅ |
| 查看自己的订单 | ✅ | ✅ |
| 查看所有订单 | ❌ | ✅ |
| 取消自己的订单 | ✅ | ✅ |
| 取消任何订单 | ❌ | ✅ |
| 发起支付 | ✅ | ✅ |
| 处理退款 | ❌ | ✅ |
▶ 示例: 用户故事
TEXT
📖 仅展示
As a CUSTOMER, I want to:
- Browse and search products
- Add products to cart (future)
- Place an order with multiple items
- View my order history
- Cancel an unpaid order within 30 minutes
- Pay for an order
- View payment status
As an ADMIN, I want to:
- Manage products (CRUD)
- View all orders
- Cancel any order
- Process refunds
- View business statistics
输出:
TEXT
📖 仅展示
执行成功
4. 技术选型
(1) 选型决策矩阵
| 决策点 | 选项 A | 选项 B | 选择 | 理由 |
|---|---|---|---|---|
| Web 框架 | WebMVC | WebFlux | WebMVC | CRUD 为主,并发 < 5000,WebMVC 更简单 |
| 认证方式 | Session | JWT | JWT | 微服务架构,多实例部署,无状态认证 |
| 缓存策略 | Caffeine 本地 | Redis 分布式 | L1 Caffeine + L2 Redis | 热点数据本地快,分布式缓存保证一致性 |
| 数据库 | PostgreSQL | MySQL | MySQL | 团队熟悉,生态成熟 |
| 数据库访问 | JPA | MyBatis | JPA | 对象映射更自然,减少 SQL 编写 |
| API 文档 | SpringDoc | 手写 | SpringDoc | 自动生成 OpenAPI 文档 |
(2) 技术栈总览
| 层级 | 技术 | 版本 |
|---|---|---|
| 语言 | Java | 17 LTS |
| 框架 | Spring Boot | 3.2.x |
| Web | Spring MVC | 6.x |
| 安全 | Spring Security + JWT | 6.x |
| 数据库 | MySQL | 8.0 |
| ORM | Spring Data JPA | 3.x |
| 缓存 | Caffeine + Redis | 3.x / 7.x |
| 验证 | Bean Validation | 3.x |
| 测试 | JUnit 5 + Mockito + TestContainers | 5.x |
| 文档 | SpringDoc OpenAPI | 2.x |
| 监控 | Actuator + Micrometer | 3.x |
| 部署 | Docker + Kubernetes | 24.x / 1.28 |
5. 数据库设计
(1) 完整 ER 图
erDiagram
USER ||--o{ ORDER : "places"
PRODUCT ||--o{ ORDER_ITEM : "included in"
ORDER ||--o{ ORDER_ITEM : "contains"
ORDER ||--o| PAYMENT : "has"
USER {
bigint id PK
varchar username UK
varchar email UK
varchar password_hash
varchar role
timestamp created_at
timestamp updated_at
}
PRODUCT {
bigint id PK
varchar name
varchar sku UK
decimal price
int stock
varchar category
tinyint status
timestamp created_at
timestamp updated_at
}
ORDER {
bigint id PK
bigint user_id FK
varchar order_number UK
varchar status
decimal total_amount
timestamp created_at
timestamp updated_at
}
ORDER_ITEM {
bigint id PK
bigint order_id FK
bigint product_id FK
int quantity
decimal unit_price
decimal subtotal
}
PAYMENT {
bigint id PK
bigint order_id FK
varchar transaction_id UK
varchar method
varchar status
decimal amount
timestamp paid_at
timestamp created_at
}
▶ 示例: DDL 建表语句
SQL
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
role VARCHAR(20) NOT NULL DEFAULT 'CUSTOMER',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
CREATE TABLE products (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(200) NOT NULL,
sku VARCHAR(20) NOT NULL UNIQUE,
price DECIMAL(10,2) NOT NULL,
stock INT NOT NULL DEFAULT 0,
category VARCHAR(50),
status TINYINT NOT NULL DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_product_name (name),
INDEX idx_product_category (category)
);
CREATE TABLE orders (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
order_number VARCHAR(20) NOT NULL UNIQUE,
status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
total_amount DECIMAL(10,2) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_order_user (user_id),
INDEX idx_order_status_created (status, created_at DESC),
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE TABLE order_items (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
order_id BIGINT NOT NULL,
product_id BIGINT NOT NULL,
quantity INT NOT NULL,
unit_price DECIMAL(10,2) NOT NULL,
subtotal DECIMAL(10,2) NOT NULL,
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
CREATE TABLE payments (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
order_id BIGINT NOT NULL UNIQUE,
transaction_id VARCHAR(50) UNIQUE,
method VARCHAR(20) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
amount DECIMAL(10,2) NOT NULL,
paid_at TIMESTAMP NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (order_id) REFERENCES orders(id)
);
输出:
TEXT
📖 仅展示
CREATE TABLE
6. API 规约设计
(1) RESTful API 规范
▶ 示例: API 端点清单
| 模块 | 方法 | URI | 说明 | 权限 |
|---|---|---|---|---|
| Auth | POST | /api/v1/auth/login |
登录 | Public |
| Auth | POST | /api/v1/auth/register |
注册 | Public |
| Product | GET | /api/v1/products |
商品列表 | Public |
| Product | GET | /api/v1/products/{id} |
商品详情 | Public |
| Product | POST | /api/v1/products |
创建商品 | ADMIN |
| Product | PUT | /api/v1/products/{id} |
更新商品 | ADMIN |
| Product | DELETE | /api/v1/products/{id} |
删除商品 | ADMIN |
| Order | POST | /api/v1/orders |
下单 | CUSTOMER+ |
| Order | GET | /api/v1/orders |
我的订单 | CUSTOMER+ |
| Order | GET | /api/v1/orders/{id} |
订单详情 | Owner/ADMIN |
| Order | GET | /api/v1/admin/orders |
所有订单 | ADMIN |
| Order | DELETE | /api/v1/orders/{id} |
取消订单 | Owner/ADMIN |
| Payment | POST | /api/v1/payments |
发起支付 | CUSTOMER+ |
| Payment | POST | /api/v1/payments/callback |
支付回调 | Internal |
▶ 示例: 统一响应格式
JAVA
// Success response
public record ApiResponse<T>(
int code,
String message,
T data,
Instant timestamp
) {
public static <T> ApiResponse<T> success(T data) {
return new ApiResponse<>(200, "OK", data, Instant.now());
}
public static <T> ApiResponse<T> created(T data) {
return new ApiResponse<>(201, "Created", data, Instant.now());
}
}
// Paged response
public record PagedResponse<T>(
List<T> content,
int page,
int size,
long totalElements,
int totalPages
) {}
输出:
TEXT
📖 仅展示
// 执行成功
▶ 示例: 分页排序参数
BASH
# List products with pagination, sorting, and filtering
GET /api/v1/products?page=0&size=20&sort=price,desc&category=electronics&minPrice=100&maxPrice=999
输出:
TEXT
📖 仅展示
# 命令执行成功
7. 开发计划与模块分工
▶ 示例: 迭代计划
| Sprint | 周期 | 目标 | 交付物 |
|---|---|---|---|
| Sprint 1 | Week 1-2 | 基础骨架 | 项目结构 + 认证 + 商品 CRUD |
| Sprint 2 | Week 3-4 | 核心业务 | 订单模块 + 事务 + 验证 + 异常 |
| Sprint 3 | Week 5-6 | 高级特性 | 缓存 + 定时任务 + 异步通知 |
| Sprint 4 | Week 7-8 | 运维部署 | Docker + K8s + 监控告警 |
8. 综合示例:OrderFlow 项目设计文档
MARKDOWN
# OrderFlow System Design Document
## 1. Business Requirements
- E-commerce order management system
- 4 modules: User, Product, Order, Payment
- 2 roles: CUSTOMER, ADMIN
- Expected: 10,000 DAU, 1,000 orders/day
## 2. Tech Stack
- Java 17 + Spring Boot 3.2.x
- MySQL 8.0 + Spring Data JPA
- Redis 7 + Caffeine (two-level cache)
- Spring Security + JWT (OAuth2 Resource Server)
- Docker + Kubernetes deployment
## 3. Database Design
- 5 tables: users, products, orders, order_items, payments
- Indexes on high-frequency query columns
## 4. API Specification
- RESTful API with versioning (/api/v1/)
- JWT Bearer authentication
- Unified response format: ApiResponse<T>
- Pagination: page, size, sort parameters
## 5. Non-functional Requirements
- P99 latency < 100ms
- Error rate < 0.1%
- Availability > 99.9%
- Automated test coverage > 80%
❓ 常见问题
Q 为什么选 WebMVC 而不选 WebFlux?
A OrderFlow 主要是 CRUD 操作,并发量预计 < 5000 QPS,WebMVC 更简单成熟。WebFlux 适合 I/O 密集、高并发、实时流场景,CRUD 项目用它反而增加复杂度。
Q 为什么用两级缓存而不是只用 Redis?
A L1 Caffeine 速度最快(纳秒级),L2 Redis 保证多实例一致性。热点数据命中本地缓存,降低 Redis 网络开销。
Q API 版本控制用 URL 路径还是 Header?
A URL 路径版本(/api/v1/)更直观、更易测试、更 SEO 友好。Header 版本更 RESTful 但调试困难。实战推荐 URL 版本。
Q 支付回调如何保证安全?
A 1)回调 URL 仅内网可达;2)验证回调签名;3)幂等处理(重复回调不重复扣款);4)记录回调日志用于对账。
Q 如何处理数据库设计中的软删除 vs 硬删除?
A 关键业务数据(订单、支付)用软删除(status=CANCELLED),保留审计记录。辅助数据(测试商品)可以硬删除。软删除需要在所有查询中过滤已删除记录。
Q 项目设计文档应该多详细?
A 足够让新成员理解系统全貌即可。包含:业务需求、技术选型及理由、数据库设计、API 规约、非功能需求。代码实现细节不需要写,代码本身就是最详细的文档。
📖 小节
- 需求分析明确四大模块和角色权限矩阵
- 技术选型用决策矩阵对比,WebMVC + JWT + 两级缓存 + MySQL + JPA
- 数据库 ER 设计五张表,索引覆盖高频查询
- API 规约统一 URI 命名、版本控制、分页排序、响应格式
- 开发计划分 4 个 Sprint,每 2 周一个迭代
- 项目设计文档是开发团队的"合同"
📝 作业
-
基础题(难度⭐):完成 OrderFlow 的需求分析文档,列出所有用户故事和 API 端点清单。
-
进阶题(难度⭐⭐):完成数据库 ER 设计和 DDL 建表语句,包含所有索引。设计统一响应格式和错误码体系。
-
挑战题(难度⭐⭐⭐):使用 SpringDoc OpenAPI 编写 API 规约,生成可交互的 API 文档页面,思考 API 文档与代码实现如何保持同步。