ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

JSP+MySQL学生成绩管理系统源码解析与二次改造实战

JSP+MySQL学生成绩管理系统源码解析与二次改造实战 简介本资源是一套基于JavaJSP与MySQL开发的B/S结构学生成绩综合管理系统面向计算机相关专业课程设计、毕业设计及Java Web入门学习者帮助解决教务信息管理中成绩录入、查询与留言互动等实际需求。压缩包共238个文件约2.92MB以gif、png、jpg等界面素材和jsp页面为主辅以js脚本、htm静态页、xml配置、java源码、class编译文件及sql建库脚本并附docx说明文档完整呈现项目结构与运行所需资源。系统按角色划分为学生、教师、教务人员三大模块学生可登录、查询各科成绩并在线留言教师可录入成绩、回复留言教务人员负责学生信息添加与修改等管理操作。目前已有531人学习下载适合需要参考完整教务系统实现思路、数据库设计与前后端交互逻辑的读者可据此快速理解JSPMySQL项目的开发流程与模块划分。1. 从一份 JSP 成绩管理源码说起编号 100010065 能跑起来吗编号 100010065 的这份资源是一套基于 JavaJSP MySQL 的 Web 学生成绩综合管理系统B/S 结构典型的课程设计交付物。拿到手第一件事不是急着导入 IDE而是先判断它能不能跑、跑起来要补哪些环境。我见过太多人把这类包直接丢进 Eclipse 就点运行结果 404、500、乱码三连最后怪源码是假的。其实问题基本都出在 JDK 版本、Tomcat 版本、MySQL 驱动版本这三者的错配上。这套系统适合三类人正在做课程设计需要参考完整 CRUD 流程的学生、想复习 JSP 原生开发不用框架的 Java 初学者、以及需要一套能改造成自己业务的管理后台骨架的开发者。它不依赖 Spring纯 JSP Servlet JDBC反而更容易看清请求从浏览器到数据库的完整链路。下面按「环境怎么搭 → 代码怎么读 → 坑在哪 → 怎么改成自己的」这条线拆开讲。2. 环境搭建JDK、Tomcat、MySQL 三件套的版本咬合2.1 为什么这套老项目对版本这么敏感JSP Servlet 的原生项目编译期依赖servlet-api.jar运行期依赖 Tomcat 提供的容器实现。如果 JDK 用 17Tomcat 用 10那javax.servlet包名已经变成jakarta.servlet源码里所有import javax.servlet.*全部报红这不是配置问题是命名空间迁移改起来要动几十个文件。所以这类编号课程设计包稳妥组合是 JDK 8 Tomcat 8.5 或 9 MySQL 5.7。MySQL 8 也能用但驱动类名和连接串参数要改后面避坑章会细说。我一般会先看源码里WEB-INF/lib下有没有mysql-connector-java-5.x.jar有就说明作者是按 MySQL 5 写的别硬上 8。2.2 三步把运行环境立起来第一步装 JDK 8 并配JAVA_HOME。Windows 下装完在系统变量里加# 验证 JDK 版本必须是 1.8.x java -version # 输出类似 java version 1.8.0_381第二步解压 Tomcat 到无中文无空格的路径比如D:\dev\tomcat9。启动前改conf/server.xml里的端口避免和已占用端口冲突!-- conf/server.xml 中找到 Connector把 8080 改成 8081 -- Connector port8081 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 /第三步MySQL 建库并导入 SQL。资源包里通常有个db.sql或school.sql先建库再导-- 建库字符集必须 utf8mb4否则中文姓名会变问号 CREATE DATABASE student_score DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE student_score; -- 然后执行资源包里的建表与初始数据脚本 SOURCE D:/resource/db.sql;这三步做完把项目文件夹整个拷进tomcat/webapps/启动bin/startup.bat浏览器访问http://localhost:8081/项目名/。能出登录页环境就算通了。出不来就去看logs/catalina.out报错第一行往往就是根因。2.3 数据库连接配置改哪里JSP 项目一般把连接参数写在src下的工具类里常见文件名是DBUtil.java或DBHelper.java。找到后改这几项// DBUtil.java 典型写法 private static final String DRIVER com.mysql.jdbc.Driver; // MySQL 5 用这个 private static final String URL jdbc:mysql://localhost:3306/student_score?useUnicodetruecharacterEncodingutf8; private static final String USER root; private static final String PASSWORD 你的密码;characterEncodingutf8这个参数不能省省了插入中文成绩单就是乱码。useUnicodetrue配合它一起用。如果换成 MySQL 8驱动类改成com.mysql.cj.jdbc.DriverURL 后面加serverTimezoneAsia/Shanghai否则启动就抛时区异常。改完重新编译别只改.java不重新 buildTomcat 跑的还是旧 class。3. 代码结构拆解从登录到成绩录入的完整链路3.1 目录结构与请求流转这套系统的典型目录是WebContent或web下放 JSP 页面src下放 Servlet 和 DAO。登录流程是login.jsp表单 POST 到LoginServletServlet 调UserDao.findByUsername()查到了就把用户对象塞进session然后response.sendRedirect(main.jsp)。成绩录入流程类似score_add.jsp提交到ScoreServletServlet 调ScoreDao.insert()成功后重定向回列表页。理解这条链路改功能就是改对应的 Servlet 和 DAO不用动 JSP 结构。3.2 一个 DAO 方法的完整写法与参数说明看一个成绩查询的 DAO 方法这是全项目复用最多的模式// ScoreDao.java 按学号查成绩 public ListScore findByStudentNo(String studentNo) { ListScore list new ArrayList(); String sql SELECT s.id, st.name, c.course_name, s.score FROM score s JOIN student st ON s.student_id st.id JOIN course c ON s.course_id c.id WHERE st.student_no ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, studentNo); // 参数下标从 1 开始不是 0 try (ResultSet rs ps.executeQuery()) { while (rs.next()) { Score sc new Score(); sc.setStudentName(rs.getString(name)); sc.setCourseName(rs.getString(course_name)); sc.setScore(rs.getDouble(score)); list.add(sc); } } } catch (SQLException e) { e.printStackTrace(); // 生产环境应换成日志 } return list; }逻辑说明用PreparedStatement而不是字符串拼接是为了防 SQL 注入学号里带单引号也不会出事。try-with-resources保证连接和结果集自动关闭避免连接池耗尽。参数说明ps.setString(1, studentNo)的 1 对应 SQL 里第一个?多个参数就按顺序 1、2、3 往下排。rs.getString(name)里的字段名要和 SELECT 的别名一致写错就抛Column not found。这个方法返回 ListServlet 拿到后request.setAttribute(scores, list)JSP 用 JSTL 的c:forEach遍历渲染成表格。3.3 分页查询怎么加原生 JSP 项目默认可能是全量查询数据一多页面就卡。加个分页核心是LIMIT两个参数// 分页查询pageNo 从 1 开始pageSize 每页条数 public ListScore findByPage(int pageNo, int pageSize) { ListScore list new ArrayList(); String sql SELECT * FROM score ORDER BY id DESC LIMIT ?, ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, (pageNo - 1) * pageSize); // 偏移量 ps.setInt(2, pageSize); // 每页条数 // ... 遍历结果集同上 } catch (SQLException e) { e.printStackTrace(); } return list; }LIMIT第一个参数是偏移量公式(pageNo - 1) * pageSize第二个是每页条数。前端传pageNo时要做边界校验小于 1 按 1 处理超过总页数按最后一页处理否则会查出空列表让用户以为数据丢了。总页数用SELECT COUNT(*)单独查一次别在分页 SQL 里算。4. 避坑与排查这类课程设计包最容易翻车的五处4.1 现象启动报 ClassNotFoundException: com.mysql.jdbc.Driver原因驱动 jar 没放进WEB-INF/lib或者放的是 MySQL 8 的驱动但代码里写的还是旧类名。解决确认WEB-INF/lib下有mysql-connector-java-5.1.x.jar如果只有 8.x 的驱动把DBUtil里的DRIVER改成com.mysql.cj.jdbc.DriverURL 加serverTimezone参数。改完记得在 IDE 里刷新项目并重新部署。4.2 现象页面能打开但所有中文变问号原因数据库建库时字符集用了latin1或者 JDBC URL 没带characterEncodingutf8。解决ALTER DATABASE student_score CHARACTER SET utf8mb4;再ALTER TABLE 表名 CONVERT TO CHARACTER SET utf8mb4;同时确认 URL 参数完整。JSP 页面顶部也要有% page contentTypetext/html;charsetUTF-8 %三处字符集必须一致。4.3 现象登录成功但跳转后 session 丢失又回到登录页原因sendRedirect和forward用混了或者浏览器禁用了 Cookie。解决跳转用response.sendRedirect()时session 靠 JSESSIONID 维持如果项目里手动session.invalidate()了就会丢。检查登录成功后有没有误调invalidate。另外 Tomcat 的context.xml里如果配了cookiesfalsesession 就靠 URL 重写容易断改回默认。4.4 现象修改代码后刷新页面没变化原因Tomcat 没重新编译 JSP 或 class 文件没更新。解决JSP 改动一般会自动重编译但src下的 Java 改动必须重新 build 并重启 Tomcat。Eclipse 里确认Project Build Automatically开着或者手动Clean一次。部署目录webapps下的 class 是旧的也会导致改了没效果。4.5 现象成绩录入报 Duplicate entry 主键冲突原因表的主键没设自增或者插入时手动传了 id。解决ALTER TABLE score MODIFY id INT AUTO_INCREMENT;插入 SQL 里去掉 id 字段让数据库自己生成。如果业务上确实需要手动指定 id那就要在插入前先查重别直接怼。5. 二次改造把课程设计变成能写进简历的项目5.1 先做三处低风险改造第一处把 JDBC 直连换成连接池。原生项目每次请求都DriverManager.getConnection()并发一高就崩。引入 Druid 或 HikariCP改DBUtil从池里取连接代码结构不变性能立竿见影。第二处把e.printStackTrace()换成日志框架至少用java.util.logging或 Log4j出问题能查。第三处给所有表单加服务端校验别只靠前端required学号格式、成绩范围 0-100 都要在 Servlet 里再判一次。5.2 用一张表看清改造前后的差异改造点改造前改造后收益数据库连接每次新建连接池复用并发能力提升异常处理printStackTrace日志文件可追溯参数校验仅前端前后端双校验防脏数据分页全量查询LIMIT 分页大表不卡密码存储明文MD5 加盐安全底线5.3 验证改造是否生效的笨办法改完别急着说“应该没问题了”。我的习惯是先清空score表插 1000 条测试数据然后开两个浏览器同时登录不同账号一个录成绩一个查列表看会不会互相干扰。再用EXPLAIN看分页 SQL 有没有走索引EXPLAIN SELECT * FROM score ORDER BY id DESC LIMIT 0, 10;如果type是ALL说明全表扫描给id加主键索引或给排序字段加索引。最后把 Tomcat 日志级别调到FINE跑一遍所有功能看有没有隐藏异常。这套流程走下来项目才算真正能拿得出手。从那以后我每次拿到这类课程设计包都强制先跑通登录、再压一遍分页、最后看日志三步缺一不可。希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进