Java学生成绩管理系统课程设计:JSP+Servlet+MySQL完整交付与避坑指南
简介这是一份基于Java技术栈的学生成绩管理系统完整项目适用于Java Web初学者、课程设计或毕业设计参考。项目围绕学生信息、课程与成绩数据的管理与分析展开涵盖从界面展示、后端处理到数据库存储的完整链路。压缩包共148个文件大小约2.66MB以76个Java源码文件为主辅以50个class编译文件、2个SQL数据库脚本、4个jar依赖及6张界面截图。源码可读性较好SQL脚本便于快速初始化表结构截图可直观预览登录、成绩录入与查询等核心界面系统实现涉及MVC设计模式、Servlet/JSP交互、JDBC数据库访问、DAO层解耦、用户登录认证等常用技术同时引入Spring、JUnit、日志框架等企业级实践有助于理解Java Web项目的整体结构与开发流程。目前已有349人学习/下载资源内包含可运行源码、数据库脚本和说明性截图适合对照学习也便于在此基础上扩展二次开发。1. 先说清楚这到底是什么Java 课程设计交付包的完整形态java 学生成绩管理系统是课程设计里出现频率最高的题目之一也是 Java Web 入门绕不开的练手项目。这个压缩包把三样东西捆在一起交付源码是完整 Java 工程数据库脚本负责把表结构和测试数据一次性建好截图让你没跑起来就能预览界面。它解决的痛点很直接——课程设计要交报告、要演示、要答得上答辩问题这套组合刚好覆盖「能跑、能看、能讲」三个要求。适合两类人马上要交课程设计的在校学生和想借一个最小完整项目把 JDBC、Servlet、JSP、MySQL 串一遍的入门开发者。下面按拿到压缩包之后的实际操作顺序写从解压、建库、导包、启动到排错一步步走完。2. 技术选型与项目结构JSP Servlet MySQL 为什么是主流组合2.1 三条实现路线桌面版、JSP Web 版、Spring Boot 版怎么选拿到标题里这种「源码 数据库脚本 截图」的交付形态基本可以判断它是课程设计标准包。这类系统在实现路线上有三条常见路线选哪条直接决定你后续的工作量。第一条是 Swing 桌面版。代码量少不依赖 Tomcat双击就能跑但界面停留在上个时代答辩演示效果一般而且现在很多课程大纲已经把「Web 应用」作为硬性要求桌面版容易被老师质疑选题过于简单。第二条是 JSP Servlet JDBC MySQL这也是绝大多数 java 学生成绩管理系统源码包采用的方案。它的分层很清晰JSP 负责展示Servlet 负责接收请求和跳转DAO 层用 JDBC 操作数据库。对课程设计来说这种结构刚好能讲清楚「三层架构」这个概念答辩时每一层都能展开说几句。第三条是 Spring Boot MyBatis技术新、写起来快但很多课程设计要求必须用 JSP而且 Spring Boot 的内嵌 Tomcat 与课程设计常见的部署方式不一样新手出问题时排查成本更高。纯粹为了交课程设计没必要主动上 Spring Boot为了简历那是另一回事第 6 章会说怎么改。路线部署复杂度演示效果答辩可讲性适合场景Swing 桌面版低一般中非 Web 方向的课程JSP Servlet中好高绝大多数 Java 课程设计Spring Boot中高好中想攒现代框架经验从这类源码包的交付形态看指向的就是第二条路线后面操作全按这个组合展开。2.2 解压之后先看目录结构别急着导入 IDEA拿到压缩包先解压第一件事不是双击打开 IDEA而是先看目录结构。一个标准的 JSP Servlet 项目目录大概长这样StudentGradeSystem/ ├── src/ │ ├── com/grade/bean/ 实体类Student.java、Course.java、Score.java │ ├── com/grade/dao/ JDBC 数据访问StudentDao.java、ScoreDao.java │ ├── com/grade/servlet/ 控制层LoginServlet.java、ScoreServlet.java │ ├── com/grade/filter/ 编码过滤器CharacterEncodingFilter.java │ └── com/grade/util/ 工具类DBUtil.java ├── WebContent/ │ ├── login.jsp │ ├── studentList.jsp │ ├── scoreList.jsp │ └── WEB-INF/ │ ├── web.xml │ └── lib/ 数据库驱动 jar 放这里 ├── sql/ │ └── grade.sql └── 运行说明.txt这个结构对应着 Java Web 最经典的职责划分。bean 包里的实体类对应数据库表一列一个字段这是「面向对象编程」在课程设计里的最小体现dao 包负责写 SQL一个方法对应一条查询或一次更新servlet 包负责接收前端请求、调用 DAO、再把结果转发回 JSP。filter 包里的编码过滤器往往是整个项目能不能正常显示中文的关键后面避坑章节会专门讲。看目录时重点确认三件事sql 脚本放在哪个目录、lib 里有没有数据库驱动 jar、web.xml 里的 Servlet 映射和 JSP 页面名称是否对应。这三件确认完导入 IDEA 基本不会出大问题。2.3 三张核心表学生、课程、成绩怎么关联成绩管理系统的数据库设计是整个项目的地基。常见做法是三张表而不是一张大表这也是这类数据库脚本里最常见的结构t_student学生表学号、姓名、班级、性别t_course课程表课程号、课程名、学分t_score成绩表学号、课程号、分数为什么不把成绩直接存在学生表里因为一个学生选多门课一门课有多个学生这是典型的多对多关系。如果用一张「学生成绩」的大表每加一门课就要给同一个学生多插入一行班级和姓名这些信息会被反复冗余存储。拆成三张表之后t_score 只存学号、课程号和分数三个关键字段通过学号和课程号关联另外两张表想查「张三的 Java 成绩」一条 JOIN 就出来想统计「每门课的平均分」按课程号分组即可。这种表结构同时也是 Java 面试题里常考的数据库设计题型——「学生选课系统」表怎么设计。能在课程设计阶段把三张表的关系想明白java 基础这一块就算打牢了后面做稍微复杂一点的项目会顺很多。下一章就把这份数据库脚本真正跑起来。3. 把数据库脚本跑起来建库建表与初始化数据的完整步骤3.1 命令行执行 SQL 脚本先建库再导表数据库脚本一般有两种执行方式在 MySQL 命令行里 source或者在 Navicat / IDEA Database 工具里「运行 SQL 文件」。我习惯先用命令行把全流程走一遍因为命令行报错信息最直观能清楚看到是哪一行 SQL 出了问题。假设压缩包里的脚本叫 grade.sql里面通常已经写好了建表和 INSERT 语句也可以自己先建库再导入关键是字符集保持一致。命令行方式如下mysql -u root -pCREATE DATABASE grade_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE grade_db; SOURCE /path/to/grade.sql; SHOW TABLES;说明一下这几个命令的用意。CREATE DATABASE 指定 utf8mb4 字符集是为了让中文字段和数据在后续操作里不乱码utf8mb4 是 utf8 的超集兼容性最好SOURCE 后面跟的是脚本文件的绝对路径Windows 下注意用正斜杠最后 SHOW TABLES 确认三张表建出来了。如果表名对不上说明脚本里可能写了别的库名先检查脚本开头的 USE 语句。注意如果脚本里已经带了 CREATE DATABASE 语句就不用再手动建库重复建库会报 Database exists 错误。如果你更习惯图形化操作在 Navicat 里右键连接 → 运行 SQL 文件选中 grade.sql 执行即可。执行前在连接属性里把编码设为 utf8mb4否则脚本里的中文注释和数据可能变成乱码。这不是玄学是 MySQL 客户端和服务端字符集不一致导致的常见问题。3.2 建表 SQL 和字段参数怎么定一份典型的成绩管理建表脚本长这样下面这段 SQL 基本涵盖了课程设计需要的大部分表结构CREATE TABLE t_student ( sno VARCHAR(20) PRIMARY KEY COMMENT 学号, sname VARCHAR(50) NOT NULL COMMENT 姓名, sclass VARCHAR(50) COMMENT 班级, sex CHAR(2) DEFAULT 男 COMMENT 性别 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT学生表; CREATE TABLE t_course ( cno VARCHAR(20) PRIMARY KEY COMMENT 课程号, cname VARCHAR(50) NOT NULL COMMENT 课程名, credit DECIMAL(3,1) DEFAULT 0 COMMENT 学分 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT课程表; CREATE TABLE t_score ( id INT AUTO_INCREMENT PRIMARY KEY, sno VARCHAR(20) NOT NULL COMMENT 学号, cno VARCHAR(20) NOT NULL COMMENT 课程号, score DECIMAL(5,2) COMMENT 成绩, UNIQUE KEY uk_sno_cno (sno, cno), CONSTRAINT fk_score_student FOREIGN KEY (sno) REFERENCES t_student(sno) ON DELETE CASCADE, CONSTRAINT fk_score_course FOREIGN KEY (cno) REFERENCES t_course(cno) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT成绩表;几个关键参数值得说清楚。sno 用 VARCHAR(20) 而不是 INT因为学号是业务编号可能以 0 开头用整型会丢掉前导零score 用 DECIMAL(5,2)总共 5 位数字、小数点后 2 位比 FLOAT 更精确成绩单上的 92.50 才能完整显示UNIQUE KEY uk_sno_cno 是联合唯一索引保证同一个学生同一门课只能有一条成绩这是防止重复录入的第一道闸门外键 ON DELETE CASCADE 表示删除学生时他的成绩记录自动跟着删避免留下孤儿数据。如果你拿到的脚本里没有外键和联合唯一索引建议自己补上。很多课程设计源码为了省事只用单表主键答辩时老师问一句「怎么防止重复录入成绩」答不上来就很尴尬。补上这两个约束代码里即使忘了做重复校验数据库这一层也能兜住。3.3 初始化数据管理员账号和测试样本脚本后半部分一般是 INSERT 语句。成绩管理系统要演示测试数据必须够用——至少 5 个学生、3 门课程、每个学生都有成绩界面才好看。常见写法如下INSERT INTO t_student (sno, sname, sclass, sex) VALUES (2021001, 张三, 计算机2101, 男), (2021002, 李四, 计算机2101, 女), (2021003, 王五, 软件2102, 男); INSERT INTO t_course (cno, cname, credit) VALUES (C001, Java程序设计, 4.0), (C002, 数据结构, 3.5), (C003, 数据库原理, 3.0); INSERT INTO t_score (sno, cno, score) VALUES (2021001, C001, 92.5), (2021001, C002, 85.0), (2021002, C001, 78.0), (2021003, C003, 88.5);管理员账号一般单独放一张 t_admin 表脚本里常见的做法是直接插入一条记录CREATE TABLE t_admin ( username VARCHAR(30) PRIMARY KEY, password VARCHAR(64) NOT NULL ); INSERT INTO t_admin (username, password) VALUES (admin, MD5(123456));这里有个值得注意的点明文密码和 MD5 加密的选择。课程设计的源码包里密码大多以 MD5 形式存储登录时把用户输入也做一次 MD5 再比对。虽然 MD5 现在已经不算安全加密但课程设计层面用它足够而且答辩时可以说「密码不是明文存储」比存明文更有说头。如果有心把 MD5 换成加盐的 SHA-256代码改动量也不大。初始化数据执行完后用一条联合查询验证数据是否就位SELECT s.sno, s.sname, c.cname, sc.score FROM t_score sc JOIN t_student s ON sc.sno s.sno JOIN t_course c ON sc.cno c.cno;能看到三张表的数据正确关联数据库这块就齐活了接下来进入源码阶段。4. 源码导入 IDEA 跑通从 Tomcat 配置到看见第一张成绩表4.1 版本匹配JDK、Tomcat、MySQL 三者的兼容关系导入源码之前先确认环境版本这是整个流程里最容易翻车的一步。课程设计源码大多是 JDK 8 时代的产物配套 Tomcat 8.5 或 9 最稳妥。如果你的机器上装的是 JDK 17 或更高Servlet 和 JSP 版本都可能不兼容常见现象是项目能编译但访问页面时报 500或者 IDEA 里找不到对应的 Tomcat 运行选项。我一般会这样做先看 web.xml 里的声明版本。web.xml 头部的 version 属性比如 version3.1 对应 Tomcat 8.5 和 JDK 8version4.0 对应 Tomcat 9。如果源码的 web.xml 是 version2.5那是一个非常老的 Servlet 规格建议手动改成 3.1 并确认注解方式可用否则在 Tomcat 9 上跑容易出兼容问题。MySQL 这边注意驱动版本要和数据库版本匹配。MySQL 5.7 用 5.x 的 mysql-connector-java 没问题MySQL 8.0 必须用 8.x 的驱动否则会报时区相关的错误。这也是「java 环境配置」里大家问得最多的一类问题——不是 JDK 没配好而是组件之间的版本互相不认。整体思路是JDK 8 Tomcat 8.5/9 MySQL 5.7/8.0这是课程设计最稳的组合。4.2 数据库连接配置四个必改参数和一个驱动包源码里数据库连接信息通常集中在 db.properties 或 DBUtil.java 里。JSP Servlet 项目的常见写法是 db.properties 放在 src 根目录内容大致如下jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/grade_db?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8 jdbc.usernameroot jdbc.password123456四个必改参数缺一个都起不来。driver 是驱动类全名MySQL 5.x 对应 com.mysql.jdbc.DriverMySQL 8.x 对应 com.mysql.cj.jdbc.Driver写错了直接报 ClassNotFoundExceptionurl 里 localhost:3306 是数据库地址和端口grade_db 是你建的库名后面三个参数 useSSLfalse 关闭 SSL 警告、serverTimezoneAsia/Shanghai 解决时区报错、characterEncodingutf8 保证中文正常写入username 和 password 换成你自己的数据库账号。还有个容易被忽略的配置驱动 jar 必须放在 WebContent/WEB-INF/lib 目录下。很多新手把 mysql-connector-java 的 jar 加到了 IDEA 的 classpath 里但 Tomcat 运行 web 应用时只认 WEB-INF/lib 下的 jar结果编译没问题、运行时抛 SQLException: No suitable driver found。检查这一处比改十行代码都有效。提示改完 db.properties 后一定要重启 Tomcat属性文件不会热加载这是新手最常见的「改了半天没生效」的原因。4.3 核心代码模块走读登录、成绩列表、增删改查的套路跑通整个项目之后建议把三个核心模块的代码读一遍登录、成绩列表、成绩的增删改查。这三个模块覆盖了 Java Web 课程设计的全部套路。登录模块的核心是 LoginServlet代码模式基本一致WebServlet(/login) public class LoginServlet extends HttpServlet { Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding(UTF-8); String username req.getParameter(username); String password req.getParameter(password); AdminDao dao new AdminDao(); Admin admin dao.findByUsernameAndPwd(username, password); if (admin ! null) { req.getSession().setAttribute(loginUser, admin); resp.sendRedirect(req.getContextPath() /scoreList); } else { req.setAttribute(errorMsg, 用户名或密码错误); req.getRequestDispatcher(/login.jsp).forward(req, resp); } } }这段代码的逻辑是先设置请求编码这是中文参数不乱码的前提然后从表单拿用户名和密码调用 DAO 去数据库比对比对成功就把用户对象塞进 session重定向到成绩列表页失败则把错误信息放进 request转发回登录页。注意 redirect 和 forward 的区别重定向是浏览器重新发一次请求转发是服务器内部完成页面切换。登录成功后用重定向能避免刷新页面时重复提交表单。成绩列表通常要加分页DAO 里对应的 SQL 是public ListScoreVO findPage(int page, int pageSize) { String sql SELECT s.sno, s.sname, c.cname, sc.score FROM t_score sc JOIN t_student s ON sc.sno s.sno JOIN t_course c ON sc.cno c.cno LIMIT ?, ?; try (PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, (page - 1) * pageSize); ps.setInt(2, pageSize); // 执行查询并封装结果集 } }LIMIT 的两个参数是 offset 和 rowcountoffset 从 0 开始所以第 1 页对应的偏移是 0第 n 页是 (n-1)*pageSize。pageSize 一般取 5 或 10前端把当前页传进来后端算出偏移量。这套分页写法在 MySQL 上通用但只适用于 MySQL——换成 SQL Server 要写 OFFSET FETCH换成 Oracle 要包一层 ROWNUM 子查询。这也是为什么有人问「java 如何连接 sql server 2008」时会发现整个 DAO 层的 SQL 都要跟着改分页语法是第一个卡点。增删改查的删改操作套路更简单表单提交 → Servlet 取值 → DAO 执行 UPDATE/DELETE → 重定向回列表页。唯一要注意的是删除操作要预判外键约束t_score 有外键指向学生表如果删的是学生而成绩表里有记录要么报外键冲突要么被级联删除实现前想清楚业务预期别把「删了学生连带删除成绩」和「有成绩就不许删学生」混着做。5. 避坑排查成绩管理系统最容易翻车的 5 个现场这套系统本身不难但跑不起来的原因千奇百怪。按出现频率把 5 个现场写下来每一条都是「现象 → 原因 → 解决」的结构照着排查比盲目改代码快得多。5.1 数据库连接失败驱动类名和 URL 是两码事现象Tomcat 启动后访问页面控制台报 java.sql.SQLException: No suitable driver found或者 Access denied for user rootlocalhost。原因前者是驱动 jar 没放到 WEB-INF/lib或者驱动类名写成了老版本的 com.mysql.jdbc.Driver 而实际用的是 MySQL 8后者是密码不对或者 root 账号只允许 localhost 连接而你用了 127.0.0.1。解决先确认 WEB-INF/lib 下有驱动 jar再确认驱动类名和 url 里的端口、库名都对得上最后用命令行 mysql -u root -p 试一下同样的账号密码能不能登录。三个检查点按顺序走基本 5 分钟内定位。顺带一提有些同学把驱动 jar 换成了高版本但数据库还是 5.7也会出现兼容告警记住驱动版本跟随数据库版本走。5.2 中文乱码全链路编码要统一现象登录后页面上的中文全是问号或者数据库里存进去的中文变成一列 ??。原因编码不一致。数据库表是 utf8mb4连接 url 没带 characterEncodingutf8JSP 页面 pageEncoding 是 ISO-8859-1Servlet 取值时没设 request 编码四层只要有一层不对中文就乱。最常见的其实是漏了 req.setCharacterEncoding(UTF-8)——GET 请求的参数在 Tomcat 8 之后默认 UTF-8POST 请求必须手动设置。解决统一为 UTF-8。数据库建库用 utf8mb4连接 url 带上 characterEncoding 参数JSP 首行写 % page pageEncodingUTF-8 %再用过滤器对所有请求统一设置编码。项目里如果已经有一个 CharacterEncodingFilter检查 web.xml 里 filter-mapping 是不是配了 /*漏了通配符等于没配。5.3 Tomcat 端口被占用8080 不是永远可用现象启动 Tomcat 时 IDEA 弹窗报 Port 8080 required by Tomcat v9.0 Server is already in use或者控制台显示 SEVERE 级别的端口绑定异常。原因本机有别的服务占用了 8080。常见的是之前跑过一次项目后 IDEA 没完全停掉 Tomcat 进程或者装了别的 Web 中间件。解决Windows 下先执行 netstat -ano | findstr 8080 找到占用进程的 PID再 taskkill /PID /F 结束它如果 8080 确实被其他应用占用且不想动可以改 conf/server.xml 里的 Connector port改成 8081 或 9090。改完记得访问地址同步换端口很多人在这一步改了端口但浏览器还敲 8080误以为项目没起来。这个问题同样会出现在「java 启动失败怎么解决」的搜索场景里本质都是同一个排查思路先看端口再看日志。5.4 数据库脚本执行报错字符集和版本兼容问题现象执行 grade.sql 时报 ERROR 1064 (42000): You have an error in your SQL syntax或者报 Unknown character set: utf8mb4。原因脚本文件本身编码不对或者 MySQL 版本太老不支持 utf8mb4utf8mb4 需要 MySQL 5.5.3 以上。有些脚本是从 Word 里复制出来的里面带着不可见字符也会触发语法错误。解决用记事本或 VS Code 把 SQL 文件另存为 UTF-8 无 BOM 格式先单独跑 CREATE DATABASE再 USE 进去跑 CREATE TABLE把报错行单独抽出来排查。如果确实是老版本 MySQL把 utf8mb4 全局替换成 utf8 就能跑代价是少支持生僻字和表情但对课程设计完全够用。5.5 截图和代码对不上先信运行说明再信代码现象按截图里的功能点去找代码发现某个页面或按钮根本不存在或者截图里是美化过的界面代码里却是简陋的默认样式。原因压缩包标题里的「截图」通常是作者早期答辩或演示时保存的和最终代码版本可能不一致也可能截图来自美化后的新版而源码包是旧版。这是网上下载课程设计源码包的常态不是个例。解决先读运行说明.txt 或 README里面一般会写清默认账号、数据库名、端口号然后以代码为准把项目跑通后再对照截图确认每个功能的入口在哪。遇到截图和代码对不上不用慌只要核心功能登录、增删改查、成绩统计在演示时用自己的实际运行画面即可答辩老师看的是你现场跑出来的效果不是压缩包里的旧图。6. 拿到源码之后怎么改从交差到能写进简历的三个进阶方向项目跑通只是第一步。如果只是交课程设计到这里已经够了但如果想让它出现在简历的项目列表里下面三个改动方向按性价比排序第一个最值得做。方向一加一个成绩统计页。成绩管理系统能查能改只是及格线能「统计」才是亮点。在现有三张表的基础上加一个按课程统计平均分、最高分、及格率的页面核心是一条 SQLSELECT c.cno, c.cname, COUNT(sc.id) AS total, ROUND(AVG(sc.score), 2) AS avg_score, MAX(sc.score) AS max_score, ROUND(SUM(sc.score 60) / COUNT(sc.id) * 100, 2) AS pass_rate FROM t_course c LEFT JOIN t_score sc ON c.cno sc.cno GROUP BY c.cno, c.cname ORDER BY avg_score DESC;这条 SQL 里 SUM(sc.score 60) 是 MySQL 的布尔求和技巧条件成立计 1不成立计 0除以总数就是及格率。新增一个 StatServlet 和 stat.jsp复用现有的 DBUtil 就能跑代码量不超过 60 行。答辩时老师问「系统有什么特色」这个统计页就是最好的回答。方向二把 JDBC 换成 MyBatis 或 MyBatis-Plus。如果时间充裕把 dao 包里的手写 JDBC 改成 Mapper 接口数据访问层的代码量能砍掉一半。现在业界的插件工具甚至可以直接根据 Java 实体类反向生成建表 SQL课程设计阶段不要求你会这个但如果你能在答辩时说清楚 JDBC 和 ORM 框架的差异面试官会高看一眼。这个改动的工程量集中在配置上实体类和表结构不用动。方向三补一份像样的 README 和部署文档。很多源码包只有「运行说明.txt」一句话你要做的是把它扩成完整文档环境要求JDK / Tomcat / MySQL 版本、数据库初始化步骤、IDEA 导入步骤、默认账号密码、各个页面的功能清单。这份文档既是课程设计报告的一部分也是以后自己回顾项目的索引——三个月后你再看这段代码全靠这份文档唤醒记忆。最后说句实在话我当年第一次跑通这种成绩管理系统时也在端口占用和驱动缺失上耗了整整一晚上。现在回头看这类项目最大的价值不是功能本身而是让你把「源码、数据库脚本、截图」这条交付链路完整体验一遍——知道代码怎么和数据库对上、知道运行环境怎么配、知道报错时该往哪个方向查。把这些手感记住后面做再大的项目也是同样的套路。希望帮到你。本文还有配套的精品资源点击获取