1. 项目概述与背景
作为一名经历过多次毕业设计指导的开发者,我深知民航订票系统这类项目在高校计算机专业中的受欢迎程度。这个基于Java+Spring Boot+MySQL的民航网上订票系统,不仅涵盖了企业级应用开发的完整流程,还能充分展示学生的技术综合运用能力。
在实际开发过程中,我发现很多同学容易陷入两个极端:要么功能过于简单难以体现技术深度,要么追求复杂功能导致项目难以完成。这个项目的巧妙之处在于,它选取了民航订票这个具有明确业务场景的领域,既保证了项目的实用性,又能在合理范围内展示技术能力。
2. 需求分析与功能设计
2.1 用户角色划分
系统采用经典的双角色设计:
- 管理员角色:
- 全权管理系统基础数据
- 处理订单和用户咨询
- 查看系统运营数据
- 维护系统字典和配置
- 普通用户角色:
- 查询和预订航班
- 管理个人账户和订单
- 与客服互动
- 浏览民航资讯
经验提示:在实际开发中,建议先完成管理员功能,再开发用户端。因为管理员功能往往涉及系统基础数据的维护,这些数据是用户功能正常运行的前提。
2.2 核心功能模块
2.2.1 航班管理模块
这是系统的核心模块,包含以下关键功能点:
- 航班信息的CRUD操作
- 航班状态管理(上架/下架)
- 座位数实时监控和预警
- 航班图片上传和管理
开发难点:
- 航班编号的自动生成规则需要精心设计
- 出发时间必须限制为未来时间
- 座位数的修改需要考虑已有订单的影响
2.2.2 订单管理模块
订单模块需要特别注意事务处理:
- 订单创建时要同时更新航班座位数
- 订单取消时要恢复对应座位
- 支付状态管理需要严谨
java复制// 示例:创建订单的事务处理
@Transactional
public Result createOrder(OrderDTO orderDTO) {
// 1. 检查座位可用性
Flight flight = flightRepository.findById(orderDTO.getFlightId());
if(flight.getAvailableSeats() < orderDTO.getSeatCount()) {
throw new BusinessException("剩余座位不足");
}
// 2. 创建订单
Order order = new Order();
// 设置订单属性...
orderRepository.save(order);
// 3. 更新航班座位
flight.setAvailableSeats(flight.getAvailableSeats() - orderDTO.getSeatCount());
flightRepository.save(flight);
// 4. 扣除用户余额
userService.deductBalance(orderDTO.getUserId(), order.getTotalPrice());
return Result.success(order);
}
2.2.3 用户管理模块
关键功能包括:
- 用户注册和登录
- 个人信息管理
- 余额管理
- 收藏夹功能
安全注意事项:
- 密码必须加密存储
- 敏感信息如身份证号需要脱敏显示
- 余额变动需要记录详细日志
3. 技术架构设计
3.1 技术选型建议
基于稳定性考虑,推荐以下技术组合:
| 技术组件 | 推荐版本 | 选择理由 |
|---|---|---|
| Java | 8 | 稳定性高,社区支持好 |
| Spring Boot | 2.5.x | 与Java 8兼容性好 |
| MySQL | 5.7 | 事务支持完善 |
| Vue.js | 2.x | 生态成熟,学习曲线平缓 |
避坑提醒:避免使用过新的技术版本,特别是Spring Boot 3.x+Java 17的组合,虽然功能强大,但遇到问题时可能难以找到解决方案。
3.2 系统架构图
系统采用典型的三层架构:
- 表现层:Vue.js前端
- 业务逻辑层:Spring Boot
- 数据访问层:MyBatis + MySQL
code复制[前端Vue] ←HTTP→ [Spring Boot] ←JDBC→ [MySQL]
↑ ↑
[Axios] [MyBatis]
3.3 数据库设计要点
3.3.1 核心表关系
- 航班表(jipiao)与订单表(jipiao_order)的一对多关系
- 用户表(yonghu)与订单表的一对多关系
- 用户表与收藏表的的一对多关系
sql复制-- 航班表结构示例
CREATE TABLE `jipiao` (
`id` int NOT NULL AUTO_INCREMENT,
`jipiao_name` varchar(100) NOT NULL COMMENT '航班标题',
`jipiao_uuid_number` varchar(50) NOT NULL COMMENT '航班编号',
`jipiao_photo` varchar(255) DEFAULT NULL COMMENT '航班照片',
`jipiao_types` int NOT NULL COMMENT '航班类型',
`jipiao_new_money` decimal(10,2) NOT NULL COMMENT '现价',
`jipiao_chufadi` varchar(100) NOT NULL COMMENT '出发地',
`jipiao_mudidi` varchar(100) NOT NULL COMMENT '目的地',
`jipiao_time` datetime NOT NULL COMMENT '出发时间',
`zuowei_number` int NOT NULL COMMENT '座位数',
`shangxia_types` int NOT NULL DEFAULT '1' COMMENT '是否上架',
`jipiao_content` text COMMENT '航班详情',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `jipiao_uuid_number` (`jipiao_uuid_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3.3.2 索引优化建议
- 航班表的出发地、目的地字段添加联合索引
- 订单表的用户ID和航班ID分别添加索引
- 出发时间字段添加单列索引
4. 关键功能实现
4.1 航班查询功能
实现要点:
- 支持多条件组合查询
- 分页处理大数据量
- 排序功能(按价格、出发时间等)
java复制// 航班查询服务实现
public Page<FlightVO> queryFlights(FlightQueryDTO queryDTO) {
return flightRepository.findAll((root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
// 出发地条件
if(StringUtils.isNotBlank(queryDTO.getDeparture())) {
predicates.add(cb.equal(root.get("jipiao_chufadi"), queryDTO.getDeparture()));
}
// 目的地条件
if(StringUtils.isNotBlank(queryDTO.getDestination())) {
predicates.add(cb.equal(root.get("jipiao_mudidi"), queryDTO.getDestination()));
}
// 出发时间范围
if(queryDTO.getStartDate() != null) {
predicates.add(cb.greaterThanOrEqualTo(root.get("jipiao_time"), queryDTO.getStartDate()));
}
if(queryDTO.getEndDate() != null) {
predicates.add(cb.lessThanOrEqualTo(root.get("jipiao_time"), queryDTO.getEndDate()));
}
// 上架状态
predicates.add(cb.equal(root.get("shangxia_types"), 1));
return cb.and(predicates.toArray(new Predicate[0]));
}, PageRequest.of(queryDTO.getPage(), queryDTO.getSize(), Sort.by("jipiao_time")));
}
4.2 订单创建功能
业务逻辑流程:
- 验证航班是否存在且可预订
- 检查用户余额是否充足
- 创建订单记录
- 更新航班座位数
- 扣除用户余额
注意事项:
- 整个过程必须在一个事务中完成
- 需要考虑并发预订的情况
- 需要设置合理的订单超时时间
4.3 文件上传处理
最佳实践:
- 文件存储在服务器文件系统,数据库中只保存路径
- 限制文件类型和大小
- 生成唯一文件名防止冲突
- 提供缩略图生成功能
java复制public String uploadImage(MultipartFile file) {
// 验证文件类型
String contentType = file.getContentType();
if(!Arrays.asList("image/jpeg", "image/png").contains(contentType)) {
throw new BusinessException("只支持JPEG和PNG格式图片");
}
// 验证文件大小
if(file.getSize() > 5 * 1024 * 1024) {
throw new BusinessException("图片大小不能超过5MB");
}
// 生成唯一文件名
String originalFilename = file.getOriginalFilename();
String fileExt = originalFilename.substring(originalFilename.lastIndexOf("."));
String newFilename = UUID.randomUUID().toString() + fileExt;
// 存储文件
Path uploadPath = Paths.get(uploadDir);
if(!Files.exists(uploadPath)) {
Files.createDirectories(uploadPath);
}
Files.copy(file.getInputStream(), uploadPath.resolve(newFilename),
StandardCopyOption.REPLACE_EXISTING);
return "/uploads/" + newFilename;
}
5. 系统测试与优化
5.1 功能测试用例设计
5.1.1 航班管理测试
| 测试场景 | 测试步骤 | 预期结果 |
|---|---|---|
| 添加新航班 | 1. 填写完整航班信息 2. 上传航班图片 3. 点击保存 |
航班列表显示新增航班,图片可正常显示 |
| 修改航班价格 | 1. 选择已有航班 2. 修改价格字段 3. 保存修改 |
航班列表中价格更新,已有订单价格不变 |
| 下架航班 | 1. 选择上架状态的航班 2. 点击下架按钮 |
航班状态变为下架,用户端不可见 |
5.1.2 订单流程测试
| 测试场景 | 测试步骤 | 预期结果 |
|---|---|---|
| 正常预订 | 1. 用户选择航班 2. 选择座位数 3. 提交订单 |
生成待支付订单,航班座位数减少 |
| 余额不足 | 1. 用户余额小于订单金额 2. 提交订单 |
提示余额不足,订单创建失败 |
| 重复预订 | 1. 用户对同一航班多次提交订单 | 提示已有待支付订单,阻止重复创建 |
5.2 性能优化建议
- 数据库层面:
- 合理设计索引
- 优化复杂查询语句
- 使用连接池配置
- 应用层面:
- 缓存热点数据(如航班信息)
- 异步处理非关键路径(如发送通知)
- 启用GZIP压缩响应数据
- 前端层面:
- 实现分页加载
- 使用CDN分发静态资源
- 压缩图片等媒体文件
6. 项目部署与运维
6.1 生产环境部署
推荐部署方案:
- 前端:
- 使用Nginx作为静态文件服务器
- 配置gzip压缩
- 设置缓存策略
- 后端:
- 使用Tomcat或Undertow作为应用服务器
- 配置JVM参数
- 设置健康检查端点
- 数据库:
- 主从复制提高可用性
- 定期备份策略
- 监控慢查询
6.2 常见问题排查
- 数据库连接失败:
- 检查连接字符串
- 验证数据库服务是否运行
- 检查网络连通性
- 文件上传失败:
- 检查目录权限
- 验证磁盘空间
- 检查文件大小限制
- 事务不生效:
- 检查@Transactional注解是否正确使用
- 确认方法是否为public
- 检查异常类型是否会被回滚
7. 毕业设计答辩技巧
7.1 演示准备
- 准备两套演示数据:
- 一套完整数据用于展示功能
- 一套简洁数据用于重点演示
- 设计演示路线:
- 管理员功能 → 用户功能 → 数据统计
- 重点展示技术难点解决方案
- 准备备用方案:
- 录屏备份
- 简化版演示流程
- 关键功能截图
7.2 问答准备
常见问题及回答思路:
- "系统如何处理高并发预订?"
- 乐观锁控制座位更新
- 队列缓冲请求
- 缓存热点航班数据
- "系统安全性如何保证?"
- 密码加密存储
- SQL注入防护
- XSS防护措施
- 敏感数据脱敏
- "项目的创新点在哪里?"
- 简洁高效的设计
- 完善的异常处理
- 良好的用户体验细节
8. 项目扩展方向
如果时间允许,可以考虑以下扩展功能:
- 微信小程序端开发
- 航班延误自动通知
- 会员积分系统
- 航班评价功能
- 第三方支付对接
对于毕业设计来说,最重要的是把核心功能做扎实,而不是追求功能的全面性。建议先确保航班管理和订单处理这两个核心模块的完整性和稳定性,再考虑其他扩展功能。