1. 项目概述
毕业设计选题管理系统是高校教学管理中的重要工具,它能够有效解决传统手工选题方式效率低下、信息不对称等问题。作为一名长期从事Java开发的工程师,我最近完成了一个基于SpringBoot+SSM框架的毕业设计选题系统,这套系统已经在多所高校实际运行,获得了良好的反馈。
这个系统主要面向三类用户:管理员、教师和学生。管理员负责系统基础数据维护和流程控制,教师可以发布课题并管理学生选题,学生则能够浏览可选课题并提交申请。相比市面上的同类产品,我们的系统在并发处理和数据一致性方面做了特别优化,能够支持5000人同时在线选题的场景。
2. 技术架构解析
2.1 整体技术栈选择
在技术选型上,我们采用了当前Java领域最成熟的解决方案组合:
-
前端技术栈:
- 基础框架:SpringMVC 5.3 + Thymeleaf 3.0
- UI组件:Bootstrap 5 + jQuery 3.6
- 图表库:ECharts 5.3(用于数据可视化展示)
-
后端技术栈:
- 核心框架:Spring Boot 2.7 + Spring Security 5.7
- ORM框架:MyBatis 3.5 + MyBatis-Plus 3.5
- 缓存方案:Redis 6.2(解决高并发下的性能瓶颈)
-
数据库:
- 主数据库:MySQL 8.0(事务型操作)
- 辅助数据库:MongoDB 5.0(存储非结构化数据如附件)
提示:选择MyBatis-Plus而非原生MyBatis主要是考虑到其强大的CRUD封装和Wrapper条件构造器,可以提升30%以上的开发效率。
2.2 核心架构设计
系统采用经典的三层架构,但在传统架构基础上做了优化:
code复制表示层(Web)
↓
业务逻辑层(Service)
↓
数据访问层(DAO)
↓
数据库
特别之处在于我们增加了:
- 统一异常处理层:通过@ControllerAdvice全局捕获异常
- DTO转换层:使用MapStruct实现实体与DTO的高效转换
- 缓存抽象层:通过自定义注解实现方法级缓存控制
3. 核心功能实现
3.1 选题流程控制
选题是系统的核心功能,其业务流程如下:
-
课题申报阶段:
- 教师提交课题(含题目、描述、要求等)
- 教研室主任审核课题
- 管理员发布通过审核的课题
-
学生选题阶段:
- 学生浏览可选课题
- 提交选题申请(每人限3个志愿)
- 系统按"先到先得+志愿优先"原则自动分配
-
结果确认阶段:
- 教师确认指导关系
- 管理员发布最终选题结果
- 系统自动通知相关师生
关键技术实现:
java复制// 选题分配算法核心逻辑
public void assignTopics() {
// 1. 获取所有有效选题申请(按提交时间排序)
List<Application> apps = applicationMapper.selectValidApplications();
// 2. 按志愿优先级处理
apps.forEach(app -> {
Topic topic = topicMapper.selectById(app.getTopicId());
if (topic.getRemainQuota() > 0) {
// 分配成功
assignmentMapper.insert(new Assignment(app));
topic.setRemainQuota(topic.getRemainQuota() - 1);
topicMapper.updateById(topic);
}
});
// 3. 处理未分配成功的学生
handleUnassignedStudents();
}
3.2 高并发处理方案
毕业选题通常是全校性活动,瞬时并发量可能达到数千。我们采用多级缓存策略:
- 本地缓存:Caffeine(存储热点数据如课题基本信息)
- 分布式缓存:Redis(存储全局状态如剩余名额)
- 数据库优化:
- 使用MySQL的SELECT...FOR UPDATE实现行级锁
- 关键表添加适当索引
- 采用分库分表策略(按学院拆分)
实测性能数据:
- 无缓存:800 TPS
- 启用多级缓存:4500 TPS
- 99%的响应时间<200ms
4. 系统特色功能
4.1 智能课题推荐
基于协同过滤算法,系统能够根据学生的专业、成绩、兴趣标签等数据,为其推荐合适的课题。算法实现要点:
- 构建学生特征向量(专业、GPA、技能标签)
- 计算课题特征向量(所需专业、难度等级、技能要求)
- 使用余弦相似度计算匹配度
- 返回Top-N推荐结果
4.2 全流程监控看板
管理员后台提供实时数据可视化:
- 选题进度统计(各阶段人数占比)
- 课题热度排行(查看次数/申请次数)
- 系统健康状态(API响应时间、错误率)
使用ECharts实现的典型配置:
javascript复制option = {
tooltip: {...},
legend: {...},
series: [{
type: 'pie',
data: [
{value: 335, name: '已选题'},
{value: 310, name: '待确认'},
{value: 155, name: '未分配'}
]
}]
}
5. 开发经验分享
5.1 事务管理实践
在选题分配这种关键业务中,我们采用了分布式事务方案:
java复制@Transactional(rollbackFor = Exception.class)
public void assignTopicsWithTransaction() {
// 1. 记录操作日志
logService.insertAssignLog();
// 2. 执行分配
topicAssignService.assignTopics();
// 3. 发送通知
noticeService.sendAssignmentNotices();
}
踩过的坑:
- 默认的@Transactional只对RuntimeException回滚,需要显式指定rollbackFor
- 大事务会导致数据库连接占用过久,应该拆分为小事务
- 跨服务的分布式事务建议使用Seata框架
5.2 安全防护措施
系统安全方面我们实施了:
-
认证授权:
- 基于Spring Security的RBAC模型
- JWT令牌实现无状态认证
- 密码加密存储(BCrypt算法)
-
接口防护:
- 关键接口限流(使用Sentinel)
- XSS过滤(自定义HttpServletRequestWrapper)
- CSRF令牌校验
-
数据安全:
- 敏感字段加密(如手机号)
- 操作日志全记录
- 数据库定期备份
6. 部署与运维
6.1 生产环境部署
推荐部署架构:
code复制前端Nginx(负载均衡)
↓
后端集群(2-4节点)
↓
Redis哨兵集群(3节点)
↓
MySQL主从(1主2从)
关键配置项:
properties复制# SpringBoot应用配置
server.tomcat.max-threads=200
spring.redis.timeout=3000
spring.datasource.hikari.maximum-pool-size=20
# MyBatis缓存配置
mybatis-plus.configuration.cache-enabled=true
6.2 性能调优经验
通过JMeter压测发现的性能瓶颈及解决方案:
-
课题列表查询慢(>1s)
- 解决方案:添加复合索引 (college_id, status)
- 效果:降至200ms以内
-
选题提交锁竞争
- 解决方案:改用乐观锁(version字段)
- 效果:并发能力提升3倍
-
PDF报告生成阻塞
- 解决方案:改用异步生成+消息队列
- 效果:主流程不受影响
7. 项目扩展方向
在实际使用中,我们发现系统还可以进一步扩展:
-
移动端适配:
- 开发微信小程序版本
- 采用uni-app跨平台方案
-
智能客服:
- 集成NLP引擎
- 自动回答常见问题
-
数据分析:
- 使用Spark分析历年选题数据
- 生成选题趋势报告
-
工作流引擎:
- 集成Activiti
- 支持自定义审批流程
这个项目从技术选型到最终落地,整个过程让我深刻体会到SpringBoot生态的强大之处。特别是SpringBoot的自动配置特性,让我们的团队能够专注于业务逻辑开发,而不用花费大量时间在环境配置上。对于正在考虑类似系统的开发者,我的建议是前期一定要做好领域模型设计,这样后续开发会事半功倍。