首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
SpringBoot+Vue+MySQL选课系统:从零到部署的完整实战拆解
📅 2026/10/23 5:29:00
✍️ 爱科研究院
👁 阅读 3,247
选课系统这名字在高校里几乎是每个学生都绕不开的东西同时也是无数计算机专业同学的大作业和毕业设计首选。我自己也帮别人调试过不少这类项目说实话市面上的选课系统源码鱼龙混杂能“拿到手就直接跑起来”的还真不多。这次要拆解的这套“大学生选修选课系统”技术栈是标准的SpringBoot后端 Vue前端 MySQL数据库主打的就是开箱即用。不管你是准备交课程设计还是想拿来学习主流前后端分离项目的完整链路这套系统都挺有参考价值。它解决的核心问题很直接学生选课、退课、查课表教师维护课程和录入成绩管理员管理用户和课程信息三个角色各干各的活儿互不干扰。这类业务场景非常典型几乎囊括了CRUD、权限控制、复杂查询、多表关联这些后端开发的基础功再加上前端页面的交互设计和状态管理一套走完你对整个前后端分离项目的理解基本就通透了。这篇文章我不会只贴几张截图敷衍了事而是把它当成一个自己亲手从零梳理过的项目把技术选型的理由、数据库怎么设计、核心业务逻辑怎么写、前后端怎么对接、以及本地怎么一步步跑起来还有我调试过程中踩过的坑全部摊开讲清楚。内容更适合有一定Java和前端基础、但还没完整做过一个项目的同学也适合拿了源码但不知道怎么入手的初学者。1. 整体设计思路与技术选型背后的考量1.1 这个系统到底在管什么选修选课系统的业务边界说复杂也复杂说简单也简单。核心就是围绕“课程”这个中心把学生、教师、管理员三类角色的操作串起来学生端浏览可选课程列表、按条件筛选课程、选择课程、退选课程、查看个人课表和个人已选课程。教师端维护自己负责的课程信息查看选课学生名单录入或者修改学生成绩。管理员端用户管理学生、教师账号的增删改查、课程管理开课、停课、调整课程参数、以及一些统计功能比如某门课的选课人数。这套系统把这三个端都做齐了不是那种只做个学生端查询的阉割版。这一点很关键因为有完整角色闭环的项目才真正具备“系统”的样子也才能让你在答辩或者讲项目的时候有话可说。1.2 为什么是SpringBoot、Vue和MySQL这个组合先说后端。SpringBoot现在基本是Java后端开发的事实标准它把繁琐的配置大量自动化内嵌Tomcat打jar包就能跑对于学生项目和学习项目来说学习成本低、生态成熟、资料多。你遇到任何报错搜索引擎上几乎都能找到答案。相比之下如果换成SSHStrutsSpringHibernate那套老古董光配置就能劝退一批人。前端选Vue是因为它的渐进式特点很适合中小型项目。你不需要一开始就引入完整的工程化全家桶可以用Vue CLI或者Vite搭一个单页应用配合Vue Router做页面跳转、Vuex或Pinia做状态管理再配合Element UI或者Element Plus做后台管理界面开发效率非常高。而且Vue的响应式机制对于课表、选课列表这种数据联动场景特别顺手——学生选了一门课剩余容量和已选列表要立刻刷新这种交互用Vue写起来心智负担很小。MySQL就更不用说了关系型数据库里最普及的选择轻量、稳定、SQL标准支持好选课系统这种典型的强事务、强关系业务用MySQL再合适不过。你可能听说过NoSQL但选课业务里学生和课程、课程和教师之间的关联以及选课时的容量扣减和唯一性约束用关系型数据库来表达才是最自然的。补充一点这套系统是前后端分离的架构也就是后端只提供JSON接口前端负责渲染页面。这跟传统的JSPServlet那种服务端渲染完全是两个思路。分离的好处是职责清晰前端改样式不影响后端逻辑后端加接口不影响前端页面也贴近目前企业里主流的工作模式。1.3 “可直接运行”到底意味着什么标题里强调“可直接运行”这句话不能只当广告看。很多网上下的源码要么缺少依赖、要么数据库脚本对不上、要么前端没编译就扔给你跑起来能折腾你两三天。这个项目所谓的可直接运行我理解是达到了这么几个标准后端代码完整Maven依赖齐全启动类、配置类、拦截器、工具类都在。前端项目依赖完整安装依赖后能正常启动开发服务器。提供完整的SQL脚本建库建表加初始数据一步到位。配置文件里的数据库连接信息、端口号、上传路径等都有明确说明。真正跑起来之后你会发现它不像某些项目那样需要你去补一堆缺失的类或者手动建表这一点在下面的实操部分会给你一步步验证。2. 核心模块拆解与数据库设计2.1 功能模块划分整个系统的功能可以用一张表说清楚角色核心功能典型操作学生选课、退课、查课浏览课程列表、按名称/教师/学分筛选、点击选课、查看个人已选列表学生课表查看按星期和节次查看本周课程时间安排教师课程管理添加课程、修改课程容量和上课时间、停课教师成绩管理查看选课学生名单、录入成绩、修改成绩管理员用户管理新增学生账号、新增教师账号、重置密码、删除账号管理员课程审核与管理对所有课程进行查看、下架、调整参数管理员数据统计统计各课程选课人数、整体选课情况这些功能对应到前端就是不同的页面和路由对应到后端就是一组组的REST接口。我在梳理代码的时候发现这个项目在模块划分上做得比较规矩没有把所有接口堆在一个Controller里而是按照业务域拆分了这种习惯值得学习。2.2 数据库表结构设计解析选课系统的表结构核心其实就那么几张。你把这个项目里的SQL脚本打开看会发现它的表设计是有讲究的用户表学生、教师、管理员统一或分表很多入门项目喜欢把学生、教师、管理员分成三张表但这个项目通常的做法是建一张用户表用角色字段区分身份。这样做的好处是登录逻辑统一只需要查一张表就能完成认证坏处是学生和教师的特有字段比如学号、工号都得塞在用户表里反而会有空字段。这个项目一般会做一点折中——用户表存公共信息再配合扩展信息。我在看代码时建议你重点研究它到底用的是哪种方案这个取舍本身就是面试常问题。课程表课程表是核心中的核心一般包含课程编号、课程名称、授课教师ID、学分、上课时间、上课地点、容量、已选人数、课程状态等字段。其中“容量”和“已选人数”这两个字段很关键选课的时候要先判断已选人数是否小于容量更新的时候要保证数据一致性。选课关系表学生选课表学生和课程是多对多关系所以必须有一张中间表来记录谁选了哪门课还包括选课时间、成绩、退课状态等字段。这张表的SQL是判断一个选课系统设计得好不好的关键——如果连中间表都没有那大概率是假项目。课程时间安排表有些项目会把上课时间单独拆出来而不是直接塞在课程表里这样做的目的是支持一门课一周有多节课的复杂场景。我在实操的时候习惯先把这几张表的ER关系理清楚再动手看代码效率会高很多。你拿到SQL脚本不要急着执行先花十分钟用工具把表关系图画出来后面看业务代码的时候脑子里会特别清楚。2.3 数据库初始化脚本的处理这个项目的SQL文件一般命名为类似course_system.sql或者db_course.sql的文件里面除了建表语句还会插入一些初始数据比如管理员账号、几个测试学生账号和教师账号、一批课程数据。这些初始数据非常重要否则你登录进去啥也看不到。执行的时候注意一点用Navicat或者命令行执行之前先检查一下MySQL的版本和字符集配置。我遇到过有人因为MySQL默认字符集不是utf8mb4导致插入中文乱码。建议执行前先确认SHOW VARIABLES LIKE character_set%;如果发现不是utf8mb4可以在MySQL配置文件里改掉再重启。这个坑虽然小但一旦踩上后面所有数据都是乱码排查起来非常头疼。3. 后端核心实现SpringBoot的业务逻辑怎么落地3.1 项目结构和关键配置拿到后端源码后第一件事是看它的包结构。常规的SpringBoot项目一般是这种分层方式controller接收前端请求返回JSON数据service业务逻辑处理mapper/dao数据库操作entity/domain实体类config配置类比如拦截器、跨域配置common/util公共返回结果、工具类exception全局异常处理这个项目基本遵循了这种结构。你在看的时候把它当成一个标准样板以后自己写项目照着这个包结构来至少不会被人说项目结构混乱。关键配置文件是application.yml或者application.properties里面主要有几项必须看明白的数据库连接配置URL、用户名、密码服务端口默认8080MyBatis或JPA的配置SQL日志、驼峰映射等这个项目如果用的是MyBatis那你会看到XML文件和Mapper接口的对应关系。如果用的是MyBatis-Plus那单表操作几乎不用写SQL服务层会清爽很多。我看这类项目一般MyBatis-Plus的概率比较大因为它确实省事。你可以通过pom.xml里的依赖判断它用的是哪一套。3.2 登录认证与权限控制的实现逻辑选课系统有三个角色登录之后不同角色看到的菜单和能访问的接口必须分开。这个项目的认证方式常见的有两种思路第一种是Session方案登录成功后把用户信息放到Session里接口通过拦截器判断是否登录、以及当前用户是否有权限访问某个接口。这种方案简单直接适合学习阶段。第二种是Token方案登录接口返回一个Token前端在后续请求里通过Header携带Token后端用一个拦截器解析Token并认证。这种方案更贴近企业实际也方便前后端分离部署。不管是哪种核心套路是一样的拦截器或过滤器统一处理请求排除登录接口本身以及静态资源其余接口校验登录状态再通过角色字段做权限判断。你在看代码的时候重点找WebMvcConfigurer的实现或者过滤器类这个就是权限控制的入口。我个人在实际帮人调试这个项目的时候发现一个经常出问题的地方是拦截器把前端的预检请求OPTIONS请求也拦截了导致跨域情况下前端报错。解决办法是在拦截器里放行OPTIONS请求或者统一配置跨域。这个问题下面第七节还会详细说。3.3 选课和退课的业务逻辑事务与并发选课这个动作看起来简单前端调一个接口后端更新两张表就完了但实际上里面有挺多点可以深挖选课接口的处理流程根据课程ID查询课程信息判断课程是否存在、状态是否正常比如是否已下架。判断当前学生是否已经选过这门课如果选过直接提示“不能重复选课”。判断课程的已选人数是否小于容量如果满了提示“课程已满”。在选课关系表插入一条记录。把课程表的已选人数加1。这里最大的问题是并发。想象一下一门课只剩一个名额两个人同时点选课如果代码里没有做并发控制两个人可能都选成功结果已选人数变成容量加一数据就错了。解决思路有几种最简单的是把课程表的这行数据加锁悲观锁也就是SELECT ... FOR UPDATE或者用版本号做乐观锁再或者靠数据库的唯一约束兜底——在选课关系表里给学生ID课程ID建唯一索引这样即使业务层没拦住数据库也会拒绝重复选课。这个项目到底用了哪种方案我建议你仔细读一读选课接口的代码和SQL脚本里有没有唯一约束。不管它用没用你自己在写的时候一定要把唯一索引加上这是成本最低、效果最稳定的兜底方案。退课接口的处理流程退课跟选课是镜像操作删除选课关系表的记录课程表的已选人数减一。但这里面还有一个坑就是退课的时间窗口问题。真实系统里一般有“开选时间”和“退课截止时间”的概念超过截止时间就不能退了。这个项目如果没做这个限制其实也说得过去因为很多课程设计的选题要求里根本没提这一点。但你自己思考的时候可以把它作为一个扩展点这也是答辩时候的加分项。3.4 成绩录入与统计查询的SQL细节教师给选课学生录入成绩本质是对选课关系表里的成绩字段做更新操作。前端界面通常是表格形式教师可以一个一个录入或者批量导入。后端接口就是一个更新方法传入选课记录ID和成绩值校验成绩范围比如0到100之后更新数据库。比较有意思的是统计功能。比如管理员要查看“每个课程的选课人数排名”这就涉及到聚合查询了SELECT c.id, c.course_name, COUNT(sc.student_id) AS selected_count FROM course c LEFT JOIN student_course sc ON c.id sc.course_id WHERE sc.is_deleted 0 GROUP BY c.id, c.course_name ORDER BY selected_count DESC;这种SQL在项目的Mapper文件里应该能看到。建议你把项目里所有超过三行的SQL都拿出来仔细读一遍每一条都对应着一个业务场景读懂它们对你SQL能力的提升比刷题快得多。4. 前端实现Vue项目如何组织和对接后端4.1 前端项目结构与工程化配置前端部分用Vue搭建拿到的目录结构通常是这样的src/api接口请求的统一封装按模块拆文件course.js、user.js、score.js等src/router路由配置定义了每个页面的路径和组件src/storeVuex或者Pinia的状态管理存用户信息和登录状态src/views页面组件比如登录页、学生首页、管理后台等src/components公共组件比如课表组件、弹窗组件src/utils工具函数比如请求封装里的拦截器看前端代码的时候先看package.json确定它用的是什么版本的Vue。如果是Vue 2配套的是Vue CLI和Element UI如果是Vue 3配套的往往是Vite和Element Plus。版本不同很多写法不一样这一点千万要留意不然照着Vue 2的文章写Vue 3的代码会怀疑人生。启动前端项目的命令一般是npm install npm run serve或者Vite项目npm install npm run dev4.2 请求封装与登录状态管理前后端分离的项目前端必须统一管理请求不能每个页面都自己写axios。通用的做法是在utils/request.js里创建一个axios实例配置好baseURL指向后端的地址比如http://localhost:8080然后通过拦截器做两件事请求拦截器从本地存储localStorage里取出Token放到请求头的Authorization字段里。响应拦截器统一处理返回结果如果后端返回的状态码表示未登录比如401就自动跳转到登录页。这个项目的登录流程通常是这样的用户在登录页输入账号密码前端调用登录接口后端校验通过后返回用户信息和Token前端把它们存进Vuex或Pinia和localStorage然后根据用户角色跳转到不同的首页。路由守卫在这里也很重要。Vue Router提供了beforeEach钩子可以在每次页面跳转前检查是否登录如果没登录就强制回到登录页同时还可以根据角色过滤可访问的页面。这段逻辑在router/index.js里是前端安全的一道重要防线。4.3 课表组件与选课页面的交互细节前端里面最值得看的我觉得是课表组件。学生查课表时后端返回的是课程时间数据比如“周一第3-4节”前端要把它渲染成一个二维表格——横轴是星期一到星期五纵轴是节次。这个渲染逻辑如果用纯JavaScript手写会比较啰嗦Vue的computed属性在这里很好用可以先把课程数据转换成二维数组再用模板循环渲染。选课页面更是典型的数据联动场景页面加载时请求课程列表用户点击选课按钮后前端先弹出确认框确认后调用选课接口成功后需要同时更新当前列表里的剩余容量和学生个人已选列表。这种多状态同步的交互在Vue里通常是把课程列表和已选列表都放在组件的data里接口返回成功后手动触发一次重新拉取或者直接用Vuex管理确保一处更新、处处响应。前端这块还有一个容易踩的坑Element UI的表格组件在数据量大的时候会出现渲染卡顿比如课程列表几百上千条时弹窗交互会有点迟钝。解决办法是分页查询让后端接口支持页码参数前端表格默认每页十条。一个“直接能跑”的项目一定已经把分页做进去了你可以验证一下。4.4 前端本地联调的跨域问题前后端分离开发最经典的坑就是跨域。前端的开发服务器默认跑在localhost:8081或者5173后端接口在localhost:8080端口不同浏览器就会因为同源策略拦截请求。解决办法通常有两个方向一是后端开启跨域在SpringBoot里写一个CorsFilter或者用CrossOrigin注解。这个项目的config包里很可能已经有跨域配置类了如果前端的页面能正常调通接口说明后端已经处理好了。二是前端配置代理在vue.config.jsVue CLI项目或vite.config.jsVite项目里设置proxy把/api开头的请求转发到后端地址。这个方案更干净上线的时候再交给Nginx做反向代理就行。我在调试的时候最喜欢用后一种方案因为这样可以保持浏览器里看到的请求地址和后端地址同源问题面更小。建议你拿到项目后先看看vue.config.js或vite.config.js里有没有代理配置如果没有就加上这一段作为参考// vue.config.js module.exports { devServer: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } };这样前端请求/api/course/list就被代理转发到http://localhost:8080/api/course/list后端的Controller收到请求时路径也能对上。如果后端接口本身没带/api前缀那代理路径和时间前缀也要相应调整不然会提示404。5. 本地运行部署全流程从环境到跑起来5.1 环境准备清单在动手之前先把需要的东西列个清单免得跑到一半发现缺东少西工具版本建议作用JDK1.8或11编译运行SpringBoot后端Maven3.6以上后端依赖管理和打包MySQL5.7或8.0数据库Node.js14以上最好16以上运行前端构建工具npm或yarn随Node附带安装前端依赖IDEIDEA或VSCode写代码看代码用Navicat或命令行任意执行SQL脚本版本的坑SpringBoot 2.x对JDK版本要求是8或11都行但如果你的项目用的是SpringBoot 3.x那JDK就必须是17以上。这个项目如果是近两年的用JDK 8编译可能会报错。拿到代码第一件事看pom.xml里的spring-boot-starter-parent版本再决定装哪个JDK别上来就装最新的。5.2 数据库初始化实操第一步打开MySQL用Navicat或者命令行创建一个数据库注意编码选utf8mb4CREATE DATABASE course_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;第二步执行项目里提供的SQL脚本。Navicat的话直接右键数据库选择“运行SQL文件”命令行的话这样mysql -u root -p course_system /path/to/course_system.sql执行完检查一下表是否都建出来了。常见的坑是SQL脚本里写了USE xxx;但那个库名和你在配置文件里写的不一样导致连不上。解决办法就是手动把脚本里的数据库名改掉或者在执行时指定库名。另外提醒一句如果你本机之前装过MySQL 8注意身份认证插件的问题。MySQL 8默认的caching_sha2_password插件在上面版本的连接工具里可能会报错解决办法是在MySQL里把用户的认证方式改成mysql_native_password。这个改法网上有标准答案我就不贴命令了反正你记住了这个关键词就能搜到。5.3 后端启动详细步骤后端启动其实不复杂但顺序很重要。第一步用IDEA打开后端项目说明一下我习惯把后端和前端各放一个文件夹这个项目通常也是这个组织方式。等Maven把依赖下载完这一步根据网络情况可能需要几分钟到十几分钟。如果下载慢可以考虑在settings.xml里配置阿里云镜像这个属于加速手段能省不少时间。第二步修改application.yml里的数据库配置spring: datasource: url: jdbc:mysql://localhost:3306/course_system?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 你的密码这一步最容易忘的是serverTimezone参数不设置的话如果用MySQL 8可能会出现时区相关的报错第一次看到那种报错你会莫名其妙加上serverTimezoneAsia/Shanghai就恢复正常了。第三步直接运行启动类就是SpringBootApplication注解标记的那个类。启动成功后控制台会打印端口号比如Tomcat started on port(s): 8080。验证方式浏览器访问http://localhost:8080/能看到一个默认的提示页面或者404页面都说明后端已经起来了。更好的验证方式是直接访问一个公开接口比如登录接口用Postman或者直接浏览器输入返回JSON就说明一切正常。一个常见的问题是端口被占用因为8080是Java项目的高频端口。如果你本机跑过其他项目占了8080可以通过server.port修改端口但前端代理配置和后端端口必须对应不然前端虽然启动了但所有接口都调不通这个问题我见过的次数太多了。5.4 前端启动详细步骤前端部分相对简单。从命令行进入前端目录依次执行下面两条命令npm install npm run servenpm install装依赖的时候如果报网络错误可以临时切换registry源这里不讨论工具细节只说明这是一个常见的网络环境问题用国内镜像源就能解决。依赖安装成功后再启动提示Compiled successfully并且给出一串本地地址比如http://localhost:8081浏览器打开就能看到登录页面了。这里有两个容易出的问题我分别说一是启动后页面白屏打开开发者工具控制台有路由报错。这种情况多半是路由模式的问题如果项目用的是history模式刷新非首页路径时会404或者白屏需要后端做路由回退或者前端改成hash模式。解决办法是把创建路由时的createWebHistory()改成createWebHashHistory()。对于本地跑着玩的学习项目来说hash模式更省事。二是页面能打开但接口全部报跨域错误。这个我前面已经说过往后端加跨域配置或者前端加代理都行。我建议先跑后端接口确认数据通没通再看前端代理配置这样排查范围更清晰。5.5 初始账号与功能验证SQL脚本里一般会有初始账号这个项目的说明文件里通常也会写明。典型的数据可能长这样角色账号密码管理员admin123456学生student或学号123456教师teacher123456登录之后建议按这条路径走一遍全流程验证管理员登录查看用户列表和课程列表。管理员新增一门课程。学生登录刷新课程列表找到刚新增的课点击选课。个人已选列表里确认出现了这门课。教师登录查看这节课的学生名单录入成绩。学生再登录查看成绩是否已显示。走完这一圈说明整个系统的主链路是通的。如果中间任何一步出问题就看下一节的问题排查技巧。6. 常见问题与排查技巧实录在帮别人调试这类项目的过程中我总结了一些高频问题这里整理成一个速查表按出现频率排序现象可能原因解决思路后端启动报数据库连接失败配置文件里的库名、账号或密码不对MySQL没启动逐个核对application.yml确认MySQL服务已启动有中文乱码数据库和连接串的字符集不是utf8mb4检查数据库字符集、SQL文件头部、JDBC连接串前端接口全部401Token没传登录状态没存拦截器放行路径没配好看请求详情里的Header检查后端拦截器exclude路径跨域报错前后端端口不同后端加CORS配置或前端加devServer代理前端页面刷新后404路由用的history模式改成hash模式或后端配置回退选课提示系统错误唯一索引冲突被业务层捕获但返回了错误信息并发异常查看后端日志清理选课表中重复的脏数据端口被占用8080或前端端口被其他进程占用netstat -ano查占用进程后结束或改端口npm install卡死网络问题更换npm镜像源6.1 后端启动失败的通用排查思路后端启动失败是最常见的但大多数人只会盯着最后几行报错看效率很低。我的习惯是三步走第一看是不是配置文件的问题。数据库连接失败、Redis连接失败如果项目用了Redis、端口被占用这些都在启动时会明确报错日志里搜Caused by就能定位到根本原因。第二看依赖是不是没下载完整。Maven项目如果依赖下载中断启动时会报“找不到类”之类的错误。解决办法是在IDEA里对项目执行clean和reimport让Maven重新解析依赖。第三如果控制台日志什么异常都没有但启动就是卡住不动那很可能是启动类所在的包路径有问题扫描不到Mapper或者Controller。检查一下SpringBootApplication所在的位置确保它放在所有包的外层。这是很多人忽略的点。6.2 前端接口调不通的排查顺序前端页面能打开但表格里空空如也这个问题也很典型。我一般按顺序检查第一打开浏览器开发者工具F12切到Network面板刷新页面看请求有没有发出。如果请求是红色报错点开看是跨域还是404还是500。第二如果是404看请求的URL前缀跟后端Controller的RequestMapping是否一致。最常见的问题是前端代理配置了/api前缀但后端接口路径没带/api结果请求发过去找不到对应的Controller。第三如果是500直接看后端控制台日志Exception信息里十有八九是SQL错误或者空指针照着修就行。第四如果是401检查登录状态是否正常。可能是Token过期或者后端拦截器把你这个请求路径给拦了还没来得及认证就返回401。6.3 我踩过的几个独特坑除了上面的常规问题还有两个比较隐蔽的坑这类问题在平时开发中很少被提起但一旦遇到真的会卡很长时间第一个是Java版本和前端依赖的年份不匹配。我遇到过项目里用的是SpringBoot 2.7依赖里引了一个比较新的加密库这个库要求JDK 11但用户机器上配的是JDK 8。表面上看编译能过运行的时候类加载报错很难联想到是版本兼容问题。解决办法就是把JDK升到11或者降低那个加密依赖的版本具体编译报错信息里会有提示。第二个是Element UI的图标字体文件加载失败。前端项目里图标显示成方块但不是代码错误而是字体文件在构建之后路径不对。这个一般通过重新构建前端或者调整publicPath配置来解决。如果只是本地开发关了浏览器缓存再刷新通常会恢复。7. 项目扩展思路与二次开发建议7.1 这个项目还能怎么升级如果你不只是想交作业还希望这个项目在你手里有一个真正的二次开发过程我给你几个方向第一个是增加排课冲突检测。现在很多选课系统只是判断容量够不够但两门课时间重叠了学生还是能选上。你可以增加一个逻辑学生选课前校验新课程的上课时间是否与已选课程时间冲突。这一步在服务层的选课方法里加判断需要把课程的时间字段做成结构化数据而不仅仅是“第1-2节”这种文本。第二个是增加选课时间窗口和抽签机制。真实选课系统里热门课程不能用“先到先得”因为学生选课时间有先有后不公平。你可以给课程表加一个“抽签结束时间”选课时先把待定状态写到中间表等截止后统一随机分配。这个扩展比较复杂但做出来之后项目的技术含量会明显上一个台阶。第三个是加消息通知。比如学生选课成功后前端弹个通知教师名单里有学生退课了也要给教师反馈。这个用简单的全局提示就能实现也可以引入WebSocket做实时推送是个不错的加分点。第四个是数据可视化。管理员首页可以放一些图表比如各课程选课人数柱状图、学生选课热门方向饼图用ECharts就能搞定。前端引入ECharts很成熟后端只需要把聚合查询的接口写好就行。7.2 二次开发时要注意什么动代码之前先把你自己的需求文档写清楚哪怕只有两行字我要改什么、现在系统里哪部分支持我改。改之前先跑通原版确认你能登录、能选课再动手。这是铁律因为你只有在一个完全正常运行的系统上做改动出了问题才知道是你改出来的而不是环境或者别人的代码本来就有问题。改动数据库表结构的时候要特别小心。比如你想给课程表加一个“课程简介”字段除了加字段本身还要同步修改实体类、Mapper XML里的SQL、前端表格的列定义、课程表单的输入项。前后端分离项目的字段变更是一条链路漏掉任何一环都会出bug。还有一个建议把项目初始化一遍把初始账号的密码改掉再加一个你自己的测试账号。这样做的好处是你二次开发的时候不会破坏初始数据否则哪天把数据测试脏了再想回到初始状态就得重新跑SQL脚本很麻烦。7.3 学习建议不要只停留在“能跑”我不止一次遇到同学拿到源码跑起来之后截个图就觉得自己完成了。我必须说一句实话能跑只是最低标准代码里的每一行都值得你读一遍。我推荐的学习路径是这样的第一次看代码不追求全懂先把请求的完整链路走一遍。从浏览器里点一个按钮开始找到前端调用的接口函数再顺着函数找到后端Controller看Service调了什么方法Mapper执行了什么SQL。走通三条链路登录、选课、查成绩之后你对这个项目的理解就跟只看代码完全不一样了。第二次看代码带着问题看。为什么要用拦截器为什么选课要加事务为什么课程表里既有容量又有已选人数每个问题都是一个技术知识点把这些想明白哪怕你一行代码都不写面试被问到这类项目也能聊得很深。第三次动手改需求。比如把选课改成“只能选三门”或者加一个“课程评价”功能。改动过程中你会遇到真正的报错、数据不一致、接口对接问题这些都是最宝贵的经验远比照着答案敲代码能学到的东西多。8. 写在最后的一点个人体会这个选课系统项目我前后帮别人看过好几轮了。每一次看我都觉得它其实是一个特别合适的练手项目——业务够真实不像图书管理那么简单技术栈够主流不是那种毕业后根本用不上的老框架代码量也适中认真读的话两三天能过完一遍。我个人的建议是拿到代码后不要急着启动先花一个小时把目录结构和数据库脚本看一遍然后按我上面说的启动流程跑起来再花一个晚上把主链路的代码走通最后挑一个自己想实现的扩展点动手改。这个过程走完你对SpringBootVueMySQL这套组合的信心会完全不一样。最后分享一个小技巧在看代码的过程中养成随手写注释的习惯把自己理解的业务流程用一两句话写在方法旁边。不用多每天积累十几个方法的注释一周之后你回头看会发现这些注释比大部分课程设计的文档都有价值。希望这篇拆解能帮你少走点弯路。如果跑起来的过程中遇到什么奇怪的报错别急着怀疑项目有问题大部分时候都是环境或者配置细节没对上。照着前面第七节的排查思路一步步来基本都能解决。祝顺利跑通也愿你能从这个项目里真正学到东西而不是只留下几张截图。
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/23 5:29:00
Windows下Redis后台启动:注册服务与配置文件实战指南
2026/10/23 5:29:00
飞行器飞行原理课件:从大气环境到伯努利方程的教学框架与避坑指南
2026/10/23 5:24:00
企业大脑落地指南:从知识工程到大模型应用的关键路径
2026/10/23 6:19:07
如何复现 ProgramBench 官方基线:用 mini-swe-agent 从零跑通完整教程
2026/10/23 6:19:07
Redis Cluster扩容的隐形瓶颈:通信开销决定集群规模上限
2026/10/23 6:19:07
C++通过COM自动化调用WPS读取Excel实战:从选型到避坑
2026/10/23 6:19:07
戴森球计划FactoryBluePrints蓝图仓库指南:从下载到一键更新的完整流程
2026/10/23 6:19:07
山洪灾害监测预警,打通预警信息传递“最后一公里”
2026/10/23 6:14:03
如何快速解决PCL2启动器内存分配显示异常:完整指南
2026/10/23 0:02:44
Verilog实现FPGA密码锁:矩阵键盘与状态机设计实战
2026/10/23 0:02:44
数据服务监控运维实战:从指标体系到告警治理与故障排查
2026/10/23 0:02:44
FreeRTOS任务通知实战详解:内核原理、API与避坑指南
2026/10/23 0:52:23
OpenResearch实战:Claude Code、Codex、OpenCode、Cursor 工作流搭建与故障排查
2026/10/22 17:15:21
知识管理核弹:用Obsidian构建第二大脑的工程化方案(TaoToken 统一 Key 接入版)
2026/10/23 0:52:11
金融AI落地指南:从调研报告到技术选型与工程实践
2026/10/22 5:06:15
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/22 2:07:18
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/21 19:01:08
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)