SpringBoot+Vue高校选课系统源码:从环境搭建到二次开发全攻略
简介这份资源是面向高校计算机相关专业学生与Java开发学习者的毕业设计参考项目围绕高校学生选课系统展开采用SpringBoot与Vue前后端分离架构后端以Java为核心、MySQL 5.7存储数据前端基于Vue.js与ElementUI构建交互界面并通过Maven管理依赖、MyBatisPlus完成持久层操作。系统覆盖学生与教师账户维护、课程发布编排、选课执行与时间冲突检测、选课结果确认查询等核心模块还支持教师上传图片与视频等多媒体教学资源整体遵循B/S模式浏览器即可访问。压缩包共695个文件约16.2MB包含131个java源码、98个vue组件、161个svg图标、38个js脚本及xml、yml配置等另有bat启动脚本与项目说明文档便于在Eclipse或IDEA中导入调试。已有74人学习适合需要完整选课系统方案、模块划分与排错思路的读者参考借鉴。1. 从一份能跑通的选课系统源码说起它到底能帮你省下多少时间如果你正在为毕业设计发愁或者想找一个前后端分离的完整项目练手这套基于 SpringBoot 与 Vue 的高校学生选课系统源码大概率能让你少熬几个通宵。它不是那种只有增删改查的玩具 Demo而是把选课系统里最典型的业务场景都覆盖了学生选课、退课、课表查看教师开课、成绩录入管理员管理课程、班级、用户和选课开关。技术栈是当前 Java 毕设里最主流的组合——后端 SpringBoot MyBatis前端 Vue Element UI数据库 MySQL。适合三类人一是毕设选题就是选课系统的同学可以直接拿来改二是想学前后端分离项目怎么落地的新手能顺着代码把请求链路走一遍三是需要快速搭一个教务类系统原型的开发者改改就能用。源码包里通常包含后端工程、前端工程和 SQL 脚本拿到手第一件事不是急着跑而是先搞清楚它的模块划分和数据表关系否则后面改需求会处处踩坑。2. 环境搭建与工程结构把 SpringBoot 和 Vue 两个工程跑起来2.1 后端工程结构与依赖版本确认拿到源码后先看后端工程的目录结构。典型的 SpringBoot 选课系统后端一般长这样src/main/java下按controller、service、mapper、entity、config、common分包resources下放application.yml、mapper/*.xml和静态资源。先打开pom.xml确认三件事SpringBoot 版本、MyBatis 版本、MySQL 驱动版本。这一步很关键因为热词里常出现「springboot版本太高」导致启动报错的情况很多源码用的是 2.x 版本如果你本地 JDK 是 17 以上直接跑可能遇到反射或依赖冲突。常见做法是JDK 用 1.8 或 11SpringBoot 用 2.5.x 到 2.7.x 之间MySQL 用 5.7 或 8.0。如果pom.xml里 SpringBoot 是 3.x那 JDK 必须 17 起步且javax.*要换成jakarta.*很多老代码会因此编译不过。确认完版本后在 IDEA 里以 Maven 项目导入等依赖下载完先别急着启动去改数据库配置。# application.yml 关键配置 server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/course_selection?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: your_password jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8 mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.entity这段配置里url的serverTimezone必须设否则 MySQL 8 会报时区错误mapper-locations决定 XML 映射文件能不能被扫描到路径写错会直接导致Invalid bound statement异常。type-aliases-package是实体类包名写错的话 XML 里resultType就得写全限定名。改完配置执行 SQL 脚本建库建表然后启动主类看到 Tomcat 端口监听就算后端通了。2.2 前端 Vue 工程安装与接口联调前端一般是 Vue 2 Element UI 或 Vue 3 Element Plus先看package.json里的vue版本和scripts。如果是 Vue 2用npm install或cnpm install装依赖Vue 3 则建议用npm install配合 Node 16 左右版本Node 版本太高有时会报OpenSSL相关错误。装完依赖后重点看vue.config.js或vite.config.js里的代理配置这是前后端联调的关键。// vue.config.js 代理配置示例 module.exports { devServer: { port: 8081, proxy: { /api: { target: http://localhost:8080, changeOrigin: true, pathRewrite: { ^/api: } } } } }这里的target指向后端地址pathRewrite决定要不要去掉/api前缀。如果后端接口本身没有/api前缀而前端请求写了/api/login那就必须重写否则 404。启动前端用npm run serve浏览器打开localhost:8081能看到登录页就说明前端通了。接下来用管理员账号登录点几个菜单看 Network 里接口返回是否正常。如果接口 500去后端控制台看堆栈如果 404检查代理和RequestMapping路径是否匹配。这一步跑通整个项目就算落地了。3. 核心业务模块拆解选课、退课与课表查询怎么实现的3.1 选课业务的事务控制与并发处理选课是这套系统的核心也是最容易出问题的地方。典型流程是学生点选课后端先查课程余量再判断是否已选、是否时间冲突最后插入选课记录并扣减余量。这四步必须在一个事务里否则并发下会出现超选。源码里一般用Transactional注解在 Service 方法上配合数据库行锁或乐观锁。Service public class CourseSelectionServiceImpl implements CourseSelectionService { Autowired private CourseMapper courseMapper; Autowired private SelectionMapper selectionMapper; Override Transactional(rollbackFor Exception.class) public void selectCourse(Integer studentId, Integer courseId) { // 1. 查询课程并加行锁防止并发超选 Course course courseMapper.selectByIdForUpdate(courseId); if (course null || course.getRemain() 0) { throw new RuntimeException(课程余量不足); } // 2. 判断是否已选 int count selectionMapper.countByStudentAndCourse(studentId, courseId); if (count 0) { throw new RuntimeException(请勿重复选课); } // 3. 插入选课记录 Selection selection new Selection(); selection.setStudentId(studentId); selection.setCourseId(courseId); selection.setSelectTime(new Date()); selectionMapper.insert(selection); // 4. 扣减余量 courseMapper.decreaseRemain(courseId); } }selectByIdForUpdate对应 SQL 里的SELECT ... FOR UPDATE这是悲观锁的常见做法能保证同一课程在并发选课时串行执行。Transactional的rollbackFor Exception.class确保任何异常都回滚避免扣了余量却没插记录。如果源码里没用锁只靠remain 0判断那在高并发下必然超选这是毕设答辩时老师最爱问的点。你可以自己用 JMeter 压一下看看有没有问题再决定要不要补锁。3.2 退课与课表查询的 SQL 实现退课逻辑相对简单但要注意两点一是退课时间窗口很多学校规定开课后不能退二是退课后余量要加回来。源码里一般用delete加update组合同样放在事务里。课表查询则是典型的关联查询学生、课程、教师三张表 join按周次和节次排序。!-- SelectionMapper.xml 课表查询 -- select idselectScheduleByStudent resultTypeScheduleVO SELECT c.course_name, c.classroom, c.week_day, c.section, t.teacher_name, c.week_start, c.week_end FROM selection s LEFT JOIN course c ON s.course_id c.id LEFT JOIN teacher t ON c.teacher_id t.id WHERE s.student_id #{studentId} ORDER BY c.week_day, c.section /select这个查询用LEFT JOIN保证即使教师信息缺失也能返回课程记录。ScheduleVO是专门为课表页面封装的视图对象包含课程名、教室、星期、节次、教师名和周次范围。前端拿到数据后按week_day和section渲染成表格。如果课表显示不全先看 SQL 返回条数再看前端循环逻辑。常见坑是week_day存的是数字 1-7前端直接显示数字而不是「周一」需要在 Vue 里做映射。4. 避坑与排查源码跑不起来时先查这五个地方4.1 数据库连接失败与时区问题现象启动后端报Communications link failure或The server time zone value is unrecognized。原因通常是 MySQL 服务没启动、端口不对、用户名密码错或者 JDBC URL 没加serverTimezone。解决先确认 MySQL 服务在跑用命令行mysql -uroot -p能登录然后检查application.yml里的urlMySQL 8 必须加serverTimezoneAsia/Shanghai如果还不行把driver-class-name换成com.mysql.cj.jdbc.Driver老版本驱动类名是com.mysql.jdbc.Driver写错会报找不到驱动。4.2 前端依赖安装报错与 Node 版本现象npm install卡住或报node-sass编译失败。原因多是 Node 版本与node-sass不兼容Vue 2 项目常见。解决用nvm切到 Node 14 或 16或者把node-sass换成sassdart-sass。如果报ERR_OSSL_EVP_UNSUPPORTED在package.json的scripts里加NODE_OPTIONS--openssl-legacy-provider或者降 Node 版本。装依赖时用npm install --registryhttps://registry.npmmirror.com换国内源能快很多。4.3 跨域与 404 问题现象前端请求后端接口报CORS或 404。原因一是后端没配跨域二是代理没生效。解决后端加CrossOrigin注解或全局配置WebMvcConfigurer的addCorsMappings前端检查vue.config.js的proxy是否配了pathRewrite是否匹配。如果请求路径是/api/xxx而后端接口是/xxx必须重写。另外注意changeOrigin: true要加上否则可能被浏览器拦截。4.4 选课并发超选现象压测时课程余量变成负数或选课人数超过容量。原因是没有加锁多个请求同时读到remain 0然后都扣减。解决在查询课程时用SELECT ... FOR UPDATE加行锁或者用乐观锁UPDATE course SET remain remain - 1 WHERE id ? AND remain 0根据影响行数判断是否成功。前者简单但性能差后者性能好但要处理重试。毕设里用悲观锁就够记得在事务里。4.5 打包部署后接口 404现象本地跑正常打成 jar 或部署到服务器后接口 404。原因可能是前端打包后静态资源路径不对或者后端context-path改了。解决前端npm run build后把dist放进后端resources/static注意publicPath设为./后端检查server.servlet.context-path如果设了/api前端请求也要加。另外 SpringBoot 打 jar 时确保spring-boot-maven-plugin配置正确否则主类找不到。5. 二次开发与扩展把选课系统改成你自己的毕设5.1 增加「选课开关」与时间冲突校验很多源码只有基础选课没有选课开关和时间冲突校验这两个点加上去毕设答辩会加分。选课开关可以在config表加一个selection_open字段管理员后台控制选课前先查这个字段。时间冲突校验需要查学生已选课程的week_day和section与新课程比对有重叠就拒绝。// 时间冲突校验逻辑 ListScheduleVO selected selectionMapper.selectScheduleByStudent(studentId); for (ScheduleVO s : selected) { if (s.getWeekDay().equals(newCourse.getWeekDay()) s.getSection().equals(newCourse.getSection()) isWeekOverlap(s, newCourse)) { throw new RuntimeException(与已选课程时间冲突); } }isWeekOverlap判断两个课程的周次范围是否有交集比如一个 1-8 周一个 5-12 周就有重叠。这段逻辑放在选课 Service 里事务内执行。加上之后选课系统的完整性就上了一个台阶。5.2 用 ECharts 做选课数据统计管理员端通常需要看选课统计比如每门课选了多少人、各学院选课分布。源码里可能只有表格你可以用 ECharts 加两个图。后端加一个统计接口返回课程名和选课人数列表前端用vue-echarts渲染柱状图。-- 选课人数统计 SELECT c.course_name, COUNT(s.id) AS count FROM course c LEFT JOIN selection s ON c.id s.course_id GROUP BY c.id, c.course_name ORDER BY count DESC这个查询按课程分组统计选课人数LEFT JOIN保证没人选的课也显示 0。前端拿到数据后传给 ECharts 的series.datax 轴用课程名。如果课程名太长可以截断或旋转标签。加上统计图后管理员页面会直观很多也方便你写论文里的「系统展示」章节。5.3 打包与部署的完整流程最后说打包部署。后端用mvn clean package生成 jar前端npm run build生成dist。把dist里的文件复制到后端src/main/resources/static重新打包这样前后端就在一个 jar 里了。启动用java -jar xxx.jar --spring.profiles.activeprod生产环境改application-prod.yml的数据库地址。如果部署到 Linux用nohup java -jar xxx.jar log.txt 21 后台运行。注意服务器上要装 JDK 和 MySQL防火墙放行端口。这套流程走一遍你就能把项目部署到云服务器答辩时直接演示线上地址。从那以后我每次拿到新源码都强制先跑通登录再顺着一条业务线把数据库、后端、前端串一遍确认没问题再改需求。希望帮到你。本文还有配套的精品资源点击获取