JavaWeb学生选课系统实训:源代码、SQL、报告与答辩PPT一次做齐

发布时间:2026/10/1 4:27:21
JavaWeb学生选课系统实训:源代码、SQL、报告与答辩PPT一次做齐 简介这份JavaWeb实训资料包面向高校计算机相关专业学生与JavaWeb初学者围绕学生选课系统这一典型课程设计场景提供从需求分析到代码落地的完整参考。系统按角色划分功能学生可注册登录、浏览课程、选课退课并查询已选结果教师可发布与删除课程、查看选课情况涵盖注册登录、学生选课、选课结果浏览、教师浏览结果、教师添加课程五大模块。包内共111个文件约20.84MB包含java源码、jsp页面、class编译文件、css与scss样式、sql建库脚本以及实训报告docx与答辩pptx另有jar依赖和字体资源结构完整便于对照复现。目前已有4575人学习下载适合需要完成课程实训、撰写报告并准备答辩的读者可据此快速理解Servlet与DAO分层写法、数据库表设计及前后端交互流程也可作为二次开发与排错参考。1. 从零交付一套 JavaWeb 学生选课系统实训报告、答辩 PPT、源代码与 SQL 文件怎么一次做齐很多同学做 JavaWeb 实训卡住的地方从来不是“不会写 Servlet”而是四件事凑不齐源代码能跑、SQL 文件能导入、实训报告有内容、答辩 PPT 讲得清。标题里这套「学生选课系统实训报告答辩ppt源代码sql文件」本质是一个完整交付包核心是选课业务外壳是课程设计验收。它适合正在做 JavaWeb 课程设计、毕业设计开题、或者想拿一个完整案例练手 MySQL 增删改查和 JSP/Servlet 的人。我见过太多人代码写了一半报告没素材PPT 只能贴截图最后答辩被问“你的选课冲突怎么判的”直接卡壳。这篇就按真实交付顺序把技术选型、库表设计、核心代码、报告与 PPT 的写法、以及最容易翻车的地方一次讲透让你照着能复现一套能过验收的系统。2. 技术选型与工程骨架为什么这套选课系统用 JSPServletMySQL 最稳2.1 选型理由别一上来就 SpringBoot标题写的是 JavaWeb 实训不是企业级微服务。很多热搜词里出现「javaweb项目完整案例mysql」「idea运行javaweb项目配置」说明大家真正需要的是一个能在 IDEA 里直接跑起来、依赖少、结构清晰的案例。这个场景下JSPServletJDBCMySQL 是最稳的组合Tomcat 一挂就能跑不需要 Maven 拉一堆依赖答辩时老师问“请求怎么走的”你能从浏览器一路讲到 DAO。如果你非要用 SpringBoot也不是不行但实训报告里要解释的东西会翻倍而且很多学校机房环境老JDK 版本低SpringBoot 3.x 直接跑不起来。常见做法是主体用 Servlet把 JDBC 工具类抽出来事务手动控制。这样既体现分层思想又不至于被框架黑匣子挡住排查路径。工程目录我一般这样组织IDE 用 IDEA构建用普通 Web 项目非 Maven 也行Maven 更规范StudentCourseSys/ ├── src/ │ ├── com/scs/entity/ # 实体类Student、Course、Teacher、SC │ ├── com/scs/dao/ # 数据访问StudentDao、CourseDao、SCDao │ ├── com/scs/service/ # 业务CourseService、SCService │ ├── com/scs/servlet/ # 控制LoginServlet、CourseServlet │ └── com/scs/util/ # DBUtil、PageUtil ├── web/ │ ├── WEB-INF/web.xml │ ├── css/ js/ │ └── *.jsp # login.jsp、course_list.jsp └── sql/scs.sql # 建库建表初始数据2.2 数据库设计四张表撑起整个选课逻辑选课系统的核心是「学生」和「课程」的多对多关系中间必须有一张选课记录表。热搜里「如何用sql文件」「javaweb项目完整案例mysql」指向的就是这块。下面是我常用的建表脚本直接存成scs.sql用 Navicat 或命令行source导入即可。-- 创建数据库字符集用 utf8mb4避免中文乱码 CREATE DATABASE IF NOT EXISTS scs DEFAULT CHARSET utf8mb4; USE scs; -- 学生表 CREATE TABLE student ( sno VARCHAR(20) PRIMARY KEY, -- 学号 sname VARCHAR(50) NOT NULL, -- 姓名 password VARCHAR(50) NOT NULL, -- 密码实训可明文生产必须加密 major VARCHAR(50) -- 专业 ); -- 课程表capacity 是容量用于判断是否选满 CREATE TABLE course ( cno VARCHAR(20) PRIMARY KEY, -- 课程号 cname VARCHAR(50) NOT NULL, -- 课程名 credit DECIMAL(3,1), -- 学分 teacher VARCHAR(50), -- 任课教师 capacity INT DEFAULT 50, -- 容量上限 selected INT DEFAULT 0 -- 已选人数 ); -- 选课记录表联合主键防止重复选课 CREATE TABLE sc ( sno VARCHAR(20), cno VARCHAR(20), score DECIMAL(5,1) DEFAULT NULL, -- 成绩选课时为空 PRIMARY KEY (sno, cno), FOREIGN KEY (sno) REFERENCES student(sno), FOREIGN KEY (cno) REFERENCES course(cno) ); -- 初始数据 INSERT INTO student VALUES (2021001,张三,123456,计算机); INSERT INTO course VALUES (C001,数据结构,4.0,李老师,50,0); INSERT INTO course VALUES (C002,操作系统,3.5,王老师,40,0);参数说明capacity和selected两个字段是选课冲突判断的关键每次选课成功要selected1退课要-1这两个操作必须和插入sc记录在同一个事务里否则会出现“人数加了但记录没插进去”的脏数据。sc表用(sno,cno)联合主键从数据库层面挡住重复选课比在 Java 里查一遍再插更可靠。2.3 IDEA 里跑通第一个页面环境配置清单热搜「idea运行javaweb项目配置」是高频卡点。按这个顺序配基本不会翻车File → Project Structure → Modules确认 Web 模块的web.xml路径指向web/WEB-INF/web.xml。Artifacts 里添加 Web Application Exploded输出目录默认即可。Run → Edit Configurations新增 Tomcat LocalDeployment 里加上刚才的 ArtifactApplication context 设成/scs。把 MySQL 驱动mysql-connector-java-8.x.jar丢进web/WEB-INF/lib并在 Project Structure → Libraries 里引入。配好后访问http://localhost:8080/scs/login.jsp能看到页面说明骨架通了。这一步不通后面全是白搭所以先跑通再写业务。3. 核心业务代码登录、选课、退课与冲突判断怎么写3.1 数据库工具类与连接管理所有 DAO 都依赖一个可靠的连接工具。实训项目不建议上连接池Druid 也行但多一个依赖手写一个DBUtil足够重点是记得关资源。public class DBUtil { private static final String URL jdbc:mysql://localhost:3306/scs?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8; private static final String USER root; private static final String PWD 你的密码; static { try { Class.forName(com.mysql.cj.jdbc.Driver); } catch (ClassNotFoundException e) { throw new RuntimeException(MySQL 驱动未加载, e); } } public static Connection getConn() throws SQLException { return DriverManager.getConnection(URL, USER, PWD); } // 统一关闭顺序ResultSet - Statement - Connection public static void close(Connection c, Statement s, ResultSet r) { try { if (r ! null) r.close(); } catch (SQLException ignored) {} try { if (s ! null) s.close(); } catch (SQLException ignored) {} try { if (c ! null) c.close(); } catch (SQLException ignored) {} } }逻辑说明serverTimezone不写会在 MySQL 8 上报时区错误这是热搜「sql访问许可验证文件出错」之外另一个高频连接坑。characterEncodingutf8保证中文课程名不乱码。关闭顺序不能反先关结果集再关连接否则可能抛异常。3.2 选课事务容量判断与重复选课一起解决选课是整个系统最容易出并发问题的地方。两个学生同时选最后一门课如果先查再插可能都查到“没满”结果超选。正确做法是把判断和更新放进一个事务并用行锁。public boolean selectCourse(String sno, String cno) { Connection conn null; PreparedStatement ps1 null, ps2 null, ps3 null; ResultSet rs null; try { conn DBUtil.getConn(); conn.setAutoCommit(false); // 开启事务 // 1. 锁定该课程行查容量 ps1 conn.prepareStatement( SELECT capacity, selected FROM course WHERE cno? FOR UPDATE); ps1.setString(1, cno); rs ps1.executeQuery(); if (!rs.next()) { conn.rollback(); return false; } int capacity rs.getInt(capacity); int selected rs.getInt(selected); if (selected capacity) { conn.rollback(); return false; } // 已满 // 2. 插入选课记录联合主键会挡住重复选课 ps2 conn.prepareStatement(INSERT INTO sc(sno,cno) VALUES(?,?)); ps2.setString(1, sno); ps2.setString(2, cno); ps2.executeUpdate(); // 3. 已选人数 1 ps3 conn.prepareStatement( UPDATE course SET selectedselected1 WHERE cno?); ps3.setString(1, cno); ps3.executeUpdate(); conn.commit(); return true; } catch (SQLIntegrityConstraintViolationException dup) { // 联合主键冲突 重复选课 try { if (conn ! null) conn.rollback(); } catch (SQLException ignored) {} return false; } catch (SQLException e) { try { if (conn ! null) conn.rollback(); } catch (SQLException ignored) {} e.printStackTrace(); return false; } finally { DBUtil.close(conn, ps1, rs); try { if (ps2 ! null) ps2.close(); } catch (SQLException ignored) {} try { if (ps3 ! null) ps3.close(); } catch (SQLException ignored) {} } }参数与逻辑说明FOR UPDATE是关键它给课程行加排他锁第二个并发请求会等第一个提交后再读避免超选。SQLIntegrityConstraintViolationException专门捕获联合主键冲突用来识别重复选课比先SELECT再判断更省一次查询。退课逻辑对称删sc记录、selected-1同样放事务里。注意setAutoCommit(false)后任何提前return都必须先rollback否则连接归还时事务还挂着这是新手最常见的翻车点。3.3 分页查询课程列表课程列表要分页否则数据一多页面卡。用LIMIT实现前端传pageNo。public ListCourse listByPage(int pageNo, int pageSize) { ListCourse list new ArrayList(); String sql SELECT * FROM course ORDER BY cno LIMIT ?, ?; try (Connection conn DBUtil.getConn(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, (pageNo - 1) * pageSize); // 起始偏移 ps.setInt(2, pageSize); // 每页条数 try (ResultSet rs ps.executeQuery()) { while (rs.next()) { Course c new Course(); c.setCno(rs.getString(cno)); c.setCname(rs.getString(cname)); c.setCredit(rs.getDouble(credit)); c.setTeacher(rs.getString(teacher)); c.setCapacity(rs.getInt(capacity)); c.setSelected(rs.getInt(selected)); list.add(c); } } } catch (SQLException e) { e.printStackTrace(); } return list; }参数说明pageNo从 1 开始偏移量是(pageNo-1)*pageSize这是分页公式写错就会出现第一页重复或漏数据。pageSize一般设 10前端 JSP 用c:forEach渲染页码用总记录数除以pageSize向上取整算。这里用了 try-with-resources比手动 close 更安全但注意它只关Connection和StatementResultSet也一起关了没问题。4. 实训报告与答辩 PPT怎么把代码变成能交差的文档4.1 实训报告的结构与素材来源热搜里「javaweb实训」「实训报告」说明文档和代码一样重要。报告不要写成代码注释的堆砌按这个骨架写每部分都有素材来源报告章节写什么素材从哪来需求分析学生选课、退课、查成绩三类用例画用例图列功能点系统设计分层架构、E-R 图、表结构第 2 章的建表脚本和目录结构详细实现关键代码流程图第 3 章的事务、分页代码测试测试用例表、截图实际跑一遍截图登录/选课/满员提示总结遇到的问题与解决第 5 章的踩坑记录E-R 图用 Visio 或 draw.io 画三个实体学生、课程、选课记录加两条关系线即可。测试章节最有说服力的是“选满后提示”和“重复选课提示”两张截图答辩老师一看就知道你真跑过。4.2 答辩 PPT 的 8 页模板PPT 别超过 10 页讲 8 分钟刚好。我常用的结构封面题目、姓名、学号、指导老师。选题背景为什么做选课系统一句话说清痛点。技术栈JSPServletMySQL配一张架构图。数据库设计E-R 图 四张表说明。核心功能演示登录、选课、退课三张截图。技术难点事务与并发选课讲FOR UPDATE。测试结果正常流程 异常流程截图。总结与不足比如“未做成绩录入后续可扩展”。第 6 页是加分项大部分同学 PPT 只贴界面你能讲出“并发下怎么保证不超选”老师印象直接拉满。演示时提前把 Tomcat 跑起来别现场启动机房环境说不准。5. 避坑与排查这套选课系统最容易翻车的 5 个地方5.1 中文乱码现象是课程名显示问号现象页面显示“?????”数据库里其实是好的。原因JSP 页面没声明编码或者请求没设字符集。解决JSP 顶部加% page contentTypetext/html;charsetUTF-8 %Servlet 里request.setCharacterEncoding(UTF-8)必须在第一次getParameter之前调用晚一行都无效。数据库连接串带上characterEncodingutf8三处齐了才彻底不乱。5.2 选课人数对不上现象是 selected 和 sc 表记录数不一致现象课程显示已选 5 人但sc表只有 4 条记录。原因插入记录和更新人数没放同一事务中间抛异常只回滚了一半。解决按 3.2 的写法两步操作包在setAutoCommit(false)和commit之间任何异常都rollback。已经脏了的数据用一条 SQL 校准UPDATE course c SET selected(SELECT COUNT(*) FROM sc WHERE cnoc.cno);。5.3 驱动报错现象是 ClassNotFound 或时区异常现象启动报com.mysql.cj.jdbc.Driver找不到或The server time zone value错误。原因驱动 jar 没放进WEB-INF/lib或连接串缺serverTimezone。解决确认 jar 在WEB-INF/lib且被 Artifact 打包连接串补上serverTimezoneAsia/Shanghai。热搜里「sql访问许可验证文件出错」多半也是连接串参数或权限问题检查用户名密码和useSSLfalse。5.4 重复选课没拦住现象是同一学生同一课程出现两条记录现象连点两次选课按钮sc表出现重复。原因表没设联合主键或前端没防重复提交。解决sc表必须PRIMARY KEY(sno,cno)Java 层捕获主键冲突异常返回“已选过”前端按钮点击后disabled双保险。5.5 部署后 404现象是本地能跑换机器就找不到页面现象访问报 404日志无异常。原因Artifact 没更新或 context path 写错。解决重新 Build Artifact确认访问路径是http://ip:8080/应用名/页面应用名和 Deployment 里的 Application context 一致。换机器时把sql文件重新导入别指望数据库跟着走。6. 让这套系统在答辩里更抗问两个进阶技巧第一个技巧是给选课加“时间冲突”判断这是老师最爱追问的点。现在只判了容量和重复如果两门课上课时间相同理论上不该同时选。做法是在course表加course_time字段如“周一1-2节”选课时查该生已选课程的course_time有交集就拒绝。SQL 用SELECT COUNT(*) FROM sc s JOIN course c ON s.cnoc.cno WHERE s.sno? AND c.course_time?命中就返回冲突。这个扩展不用改架构加一个字段和一段判断报告里能多写一节“冲突检测”PPT 多一页性价比极高。第二个技巧是准备一份“答辩问答预案”把可能被问的问题和答案写成一页纸背下来。高频问题就那几个为什么用 Servlet 不用框架答实训要求理解底层请求流程、事务怎么保证一致性答FOR UPDATE加手动提交回滚、数据量大了怎么办答加索引、上连接池、分页。我当年答辩被问“如果两个人同时选最后一门课会怎样”因为提前想过直接画了锁的时序图老师点头就过了。血泪经验是别背代码背“为什么这么写”。最后说个习惯我做完任何课程设计都会把sql文件、源码、报告、PPT 放一个文件夹命名带日期再导出一份 PDF 版报告。因为答辩现场 U 盘不认、Office 版本不兼容这种事太常见PDF 是后悔药。这套学生选课系统本身不难难的是交付完整、讲得清楚、经得起追问。把事务和冲突这两块吃透你就不只是交了个作业而是真懂了 JavaWeb 的请求-业务-数据这条链路。希望帮到你。本文还有配套的精品资源点击获取