
简介这是一套基于SpringBoot与MySQL开发的上机考试系统完整项目包面向计算机、数学、电子信息等专业的学生与教师适用于课程设计、期末大作业及毕业设计参考。系统围绕管理员、教师、学生三类角色展开通过绑定IP地址控制学生登录防止代交涵盖教师账号管理、考试创建与清理、试卷上传、学生名单导入、提交文件打包下载及通知消息推送等核心业务。压缩包共218个文件约8.42MB包含52个Java源文件、23个HTML页面、22个JavaScript脚本、6个JSP页面及CSS样式另附SQL数据库脚本、properties配置、jar依赖与需求分析设计报告文档源码与数据库齐备下载即可运行调试。目前已有91人学习关注。读者可借此掌握SpringBoot整合MySQL的实战开发流程理解UML用例图与顺序图驱动的需求分析与概要设计思路并参考完整目录结构进行二次开发与功能扩展。1. 上机考试系统源码拆包从 SpringBoot 启动到 MySQL 建库的完整链路期末周前两周实验室里最常听到的一句话是“考试系统又崩了”。老师要组织一场 200 人的上机考试学生机位分散、交卷时间集中、判分还得当场出结果用纸质签到加 U 盘收作业根本不现实。这套基于 SpringBoot MySQL 的上机考试系统源码包解决的正是这个场景教师端出题组卷、学生端限时答题、系统自动判分并落库。它适合正在做毕业设计或课程设计的同学也适合想拿一个完整 CRUD 权限 定时逻辑项目练手的 Java 初学者。压缩包里给了源码、数据库脚本和设计报告三样东西意味着你不用从零画 ER 图直接照着跑通就能改。下面我按自己拆包复现的顺序把启动、建库、配置、判分逻辑和踩坑点一条条讲清楚。2. 环境准备与项目结构JDK、Maven、MySQL 版本怎么选2.1 版本选型为什么 SpringBoot 2.x 配 MySQL 5.7 最稳拿到源码先别急着mvn spring-boot:run版本对不上是这类课程设计项目翻车的第一大原因。热词里“springboot版本太高”不是空穴来风——很多毕设源码写于 SpringBoot 2.3~2.7 时代用的还是javax.*命名空间如果你本地默认拉了 SpringBoot 3.x启动直接报jakarta.servlet找不到类。我的建议是JDK 用 8 或 11Maven 用 3.6MySQL 用 5.7.x5.7.44 是常见稳定版SpringBoot 保持源码pom.xml里声明的版本不要动。判断源码年代的土办法打开pom.xml看parent里的版本号再看import语句是javax.persistence还是jakarta.persistence。前者就是 2.x 体系别升。组件推荐版本说明JDK8 / 11与 SpringBoot 2.x 匹配Maven3.6.3依赖拉取稳定MySQL5.7.44驱动mysql-connector-java5.1.x/8.0.x 均可IDEIDEA 2021社区版够用2.2 目录结构三层架构里哪几个文件必须改解压后典型结构是src/main/java下按controller / service / mapper / entity分包src/main/resources下放application.yml和mapper/*.xml根目录有sql文件夹存建库脚本。真正需要你动手的只有三处数据库连接配置、建库脚本导入、端口占用检查。其余代码逻辑先别碰跑通再说。# 查看项目结构Linux/macOS tree -L 3 -I target # Windows 用 dir /s /b 或直接在 IDEA 左侧看上面命令只是帮你确认sql目录和application.yml的位置。逻辑说明-L 3限制三层深度避免刷屏-I target排除编译产物。参数上如果你项目里还有node_modules之类可以继续加-I排除。提示先确认sql目录里的脚本文件名常见叫exam_system.sql或db.sql后面导入要用到。3. 数据库落地建库、导表与连接配置的实操3.1 导入 SQL 脚本字符集和排序规则别踩坑建库这一步看着简单但字符集设错会导致中文题目变问号排序规则设错会让ORDER BY结果诡异。常见做法是手动建库再导表而不是直接执行脚本里的CREATE DATABASE因为脚本里的字符集未必适合你的 MySQL 版本。-- 手动建库显式指定字符集 CREATE DATABASE exam_system DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci; -- 切换库 USE exam_system; -- 再导入表结构命令行方式 -- mysql -u root -p exam_system exam_system.sql逻辑说明utf8mb4比utf8多支持 emoji 和部分生僻字题目里如果有特殊符号不会丢。utf8mb4_general_ci是不区分大小写的通用排序规则适合考试系统这种对大小写不敏感的场景。参数上如果你 MySQL 是 8.0排序规则可以换成utf8mb4_0900_ai_ci性能更好但兼容性略差。导入完成后用SHOW TABLES;确认表数量典型的上机考试系统会有user用户、exam考试、question题目、answer_record答题记录、score成绩这几张核心表。如果少表说明脚本没导全回去检查 SQL 文件是否被截断。3.2 application.yml 配置四个参数决定能不能连上连接配置是新手最容易卡住的地方。打开application.yml找到spring.datasource节点重点改四个值url、username、password、driver-class-name。spring: datasource: url: jdbc:mysql://localhost:3306/exam_system?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.Driver逻辑说明useUnicodetruecharacterEncodingutf8保证中文不乱码serverTimezoneAsia/Shanghai解决时区报错MySQL 8.0 驱动必须带否则启动报The server time zone value异常useSSLfalse关掉 SSL 警告。参数上driver-class-name如果是 MySQL 5.7 且驱动是 5.1.x可以写com.mysql.jdbc.Driver但推荐统一用com.mysql.cj.jdbc.Driver兼容性更好。改完配置先别启动整个项目用 IDEA 自带的 Database 工具或命令行mysql -u root -p连一下确认账号密码和库名无误。这一步能省掉后面一半的排查时间。3.3 启动验证看日志里这三行才算成功配置改完执行启动控制台刷屏很快但真正要盯的只有三行Tomcat 端口、数据源初始化、Mapper 加载。# Maven 方式启动 mvn spring-boot:run # 或打包后运行 mvn clean package -DskipTests java -jar target/exam-system-0.0.1-SNAPSHOT.jar逻辑说明-DskipTests跳过测试类因为课程设计项目的测试类经常依赖真实数据库本地跑会失败但不影响主程序。启动成功后日志里会出现Tomcat started on port(s): 8080、HikariPool-1 - Start completed、Mapped {[/exam/list]}这类信息。如果卡在HikariPool不动八成是数据库连不上回去查 3.2 的四个参数。浏览器访问http://localhost:8080能看到登录页就说明前后端链路通了。默认账号密码一般在设计报告或user表里常见是admin/123456或teacher/teacher。4. 核心功能拆解登录鉴权、组卷与自动判分的实现逻辑4.1 登录鉴权Session 还是 Token改哪里这套系统大概率用的是 Session 方案因为课程设计项目为了降低复杂度很少上 JWT。登录流程是前端提交账号密码 →LoginController调UserService查库比对 → 成功则session.setAttribute(user, user)→ 后续请求用拦截器校验 Session。// 典型的登录校验片段示意以源码为准 PostMapping(/login) public Result login(RequestBody User user, HttpSession session) { User dbUser userService.findByUsername(user.getUsername()); if (dbUser null || !dbUser.getPassword().equals(user.getPassword())) { return Result.error(账号或密码错误); } session.setAttribute(user, dbUser); return Result.success(dbUser); }逻辑说明这里密码是明文比对课程设计常见做法生产环境必须加 BCrypt 加密。参数上HttpSession由 Spring 自动注入不用手动创建。如果你想改成 Token需要引入jjwt依赖并重写拦截器工作量不小毕设阶段不建议动。4.2 组卷逻辑随机抽题与分值分配组卷是考试系统的核心。常见实现是教师选定题型和数量后端按ORDER BY RAND() LIMIT n抽题。这个写法在数据量小的时候没问题题目上千条后性能会下降但课程设计场景够用。-- 按题型随机抽题示意 SELECT * FROM question WHERE type single_choice ORDER BY RAND() LIMIT 10;逻辑说明ORDER BY RAND()会对全表生成随机数再排序数据量大时慢优化方案是先用COUNT取总数再随机OFFSET但毕设不必过度设计。参数上LIMIT 10对应教师设置的单选题数量实际代码里这个值来自前端传参。组卷完成后会往exam表插一条记录同时把题目 ID 和分值写入关联表。判分时按关联表逐题比对答案累加得分写入score表。4.3 自动判分客观题与主观题的边界客观题单选、多选、判断判分逻辑简单字符串比对即可。主观题简答、编程通常只存答案不自动判分留给教师人工阅卷。这是这类系统的能力边界别指望它自动判编程题。// 客观题判分示意 int score 0; for (AnswerRecord record : records) { Question q questionMapper.findById(record.getQuestionId()); if (q.getAnswer().equals(record.getUserAnswer())) { score q.getScore(); } } scoreMapper.insert(new Score(userId, examId, score));逻辑说明循环比对每题答案答对累加分值。参数上q.getScore()是题目分值来自组卷时的分配。注意多选题的比对要考虑答案顺序常见做法是排序后再比源码里如果没处理你可以自己补一个Arrays.sort。5. 避坑与排查启动失败、乱码、判分异常的常见问题5.1 启动报错Access denied for user现象控制台抛java.sql.SQLException: Access denied for user rootlocalhost。原因application.yml里的密码和 MySQL 实际密码不一致或者 MySQL 8.0 的caching_sha2_password认证插件与旧驱动不兼容。解决先确认密码再检查驱动版本MySQL 8.0 建议用mysql-connector-java 8.0.x并在 url 后加allowPublicKeyRetrievaltrue。5.2 中文题目显示为问号现象页面题目全是???。原因数据库字符集不是utf8mb4或连接 url 没带characterEncodingutf8。解决重建库时显式指定字符集url 补上编码参数已导入的数据需要重新导入。5.3 端口 8080 被占用现象启动报Port 8080 was already in use。原因本机有其他服务占了 8080常见是另一个 SpringBoot 项目或 Tomcat。解决改application.yml里的server.port为 8081 或其他空闲端口或用netstat -ano | findstr 8080找到进程杀掉。5.4 交卷后成绩为 0现象学生答完题交卷成绩记录是 0 分。原因判分时题目 ID 对不上或者答案比对时大小写、空格没处理。解决检查answer_record表里的question_id是否和question表一致比对前对答案做trim()和toLowerCase()处理。5.5 Mapper 扫描不到导致启动失败现象启动报Consider defining a bean of type xxxMapper。原因启动类上缺少MapperScan注解或注解路径写错。解决在启动类加MapperScan(com.xxx.mapper)路径按实际包名改。6. 二次开发与验证把课程设计改成能写进简历的项目跑通只是第一步真正让这套源码有价值的是二次开发。我一般会先做三件事验证系统完整性一是用教师账号组一套 10 题的卷子二是用学生账号限时答完并交卷三是查数据库确认score表有记录且分值正确。这三步走完说明核心链路没问题。进阶方向有两个。第一是加 JWT 替换 Session把登录态改成无状态这样能顺带写进简历作为亮点。第二是加考试防作弊逻辑比如切屏检测、限时自动交卷。切屏检测前端监听visibilitychange事件自动交卷后端加定时任务扫描超时未交的记录。// 切屏检测示意 document.addEventListener(visibilitychange, function() { if (document.hidden) { // 上报切屏次数 fetch(/exam/switch-screen, { method: POST }); } });逻辑说明visibilitychange在标签页切换时触发document.hidden为 true 表示离开当前页。参数上上报接口需要后端配合记录次数超过阈值可强制交卷。这个功能不难但能让你的项目从“能跑”变成“有设计”。验证方法上我习惯用 Postman 或 curl 直接打接口绕过前端确认后端逻辑。比如交卷接口curl -X POST http://localhost:8080/exam/submit \ -H Content-Type: application/json \ -d {examId:1,userId:2,answers:[{questionId:1,answer:A}]}逻辑说明直接构造 JSON 请求体测试交卷返回结果里看code和score字段。参数上examId和userId要换成数据库里真实存在的值否则会报外键或空指针。从那以后我每次拿到这类课程设计源码都强制先跑通登录、组卷、交卷、查分这条主链路再动任何一行代码。顺序反了后面全是玄学问题。希望这套拆解能帮你少走几个弯路顺利把项目跑起来、改下去。本文还有配套的精品资源点击获取