☰
Java Swing+SqlServer学生成绩管理系统完整实战指南
2026/9/28 1:14:49 网站建设 项目流程

简介:基于Java+Swing+SqlServer开发的学生成绩管理系统,面向毕业设计学生与Java桌面应用学习者。系统帮助班主任教师完成成绩录入、统计、分析和打印,包含登录、学生管理、教师管理、成绩查询、系统设置等多个功能模块,覆盖Swing界面设计与JDBC数据库访问的典型开发流程,适合作为高校课设参考或练手项目。资源共176个文件,内含31个java源文件、104个class编译文件、SqlServer数据库mdf/ldf备份、10个mp4讲解视频和多张运行界面预览图,压缩包整体183MB。源码中包括JdbcAdapter、登录窗口、学生教师管理、成绩汇总查询、系统设置等核心类,目录结构清晰便于定位。配套视频演示了数据库附加、项目导入与功能操作全过程,能帮助快速复现并深入理解Swing+SqlServer项目开发细节。目前已有187人学习下载,适合需要完整毕业设计项目或想提升Java+SqlServer实战能力的读者。

1. 学生成绩管理系统:不是玩具项目,是能答辩能上手的完整实战

做毕设最怕什么?怕拿到一个半成品,代码里全是洞,数据库连不上,讲不出逻辑。这套基于 Java+Swing+SqlServer 的学生成绩管理系统,最值钱的地方不是界面多好看,而是它的代码结构完整:从 JdbcAdapter 数据库适配层到 JF_login 登录、JF_view_teacher 教师视图、JF_view_query_grade_hz 成绩汇总查询,一套类名把 MVC 的思路拆得清清楚楚。班主任要的成绩录入、统计、分析打印都在里面,不是花架子功能。

你如果正在找 Java 课程设计或者毕业论文的支撑项目,这套能直接拿来复现:源代码、SQL Server 数据库脚本、讲解视频三件套齐了。它适合两类人——想快速把毕设跑起来、有时间研究代码的学生,以及想看看 Swing + JDBC + SqlServer 怎么组织出完整业务流的从业者。难点集中在环境配置和数据库连接上,后面我把每一步怎么走、坑在哪都拆开讲。

2. 系统模块拆解:从类名反推业务结构,看懂 JF 前缀的设计逻辑

拿到压缩包先别看代码,先看类名。这套系统的类命名非常规整,全部用 JF 开头——这不是随便起的,JF 就是 Java Frame 的缩写,说明每个类都对应一个顶层窗口。从类名就能反推整个系统的业务边界,这是拆项目的第一课。

2.1 十个核心类的职责映射,对照业务窗口读代码

我把主要类名和业务功能的对应关系列出来,你对照着看,系统结构几分钟就能心里有数:

类名业务含义备注
JF_login登录窗口系统入口,用户认证
JF_view_student学生信息管理增删改查、列表展示
JF_view_teacher教师信息管理教师账号维护
JF_view_gradesub成绩录入按班级课程录入学生成绩
JF_view_query_jbqk基本情况查询jbqk 是“基本情况”拼音缩写
JF_view_query_grade_hz成绩汇总查询hz 是“汇总”,统计分析入口
JF_view_sysset_class班级设置班级年级维护
JF_view_sysset_grade年级设置年级信息维护
JF_view_user_modify用户信息修改修改密码、个人资料
JdbcAdapter数据库连接适配器所有 JDBC 操作的统一封装

这种命名的好处非常直接:每个业务模块对应一个窗体类,窗体之间的跳转通过setVisible(true/false)控制,而不是把所有逻辑堆在一起。你读代码的时候,先打开 JdbcAdapter,看它怎么拿到 Connection,再打开 JF_login,看登录成功后跳转到哪个主窗体,整个调用链就活了。

2.2 Swing 窗体的生命周期管理,看懂 setVisible 的调用链

Swing 程序的窗体切换有个很常见的翻车点:直接new一个新窗口,旧窗口不管了,结果进程不退出,界面叠了一堆。这套系统的处理方式是标准的窗体复用——登录成功后隐藏登录窗,显示主窗,退出时统一 dispose。

// 登录成功后切换到主界面的典型写法 this.setVisible(false); // 隐藏当前登录窗口,不销毁 JF_view_teacher mainView = new JF_view_teacher(); // 创建主窗体实例 mainView.setVisible(true); // 显示主窗体

这段代码核心在两个方法上。setVisible(false)只是把窗口藏起来,实例还在内存里;真正释放资源要调dispose()。很多新手写的程序关掉窗口进程还在,就是因为只做了setVisible(false)没做dispose(),窗口对象一直占着内存。

我一般会在窗口的关闭事件里统一处理:点 X 时调用System.exit(0)或者dispose(),而不是用默认的EXIT_ON_CLOSE常量直接硬退——后者在窗口资源没有释放干净的场景下容易出诡异问题,比如再次启动时报端口占用。

2.3 JdbcAdapter 统一管理连接,所有界面共用一套数据库逻辑

这套系统里 JdbcAdapter 是最值得抄的类。它把 Connection 的获取、关闭、SQL 执行统一封装,界面层不用关心驱动加载这些脏活。

public class JdbcAdapter { private static String url = "jdbc:sqlserver://localhost:1433;DatabaseName=StudentDB;characterEncoding=utf-8"; private static String user = "sa"; private static String password = "123456"; public static Connection getConn() { try { Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); return DriverManager.getConnection(url, user, password); } catch (Exception e) { e.printStackTrace(); return null; } } public static void close(Connection conn, Statement st, ResultSet rs) { // 逆序关闭,先关结果集,再关语句,最后关连接 } }

注意几个细节。Class.forName是加载驱动类,SQL Server 2008 到 2019 通用的是com.microsoft.sqlserver.jdbc.SQLServerDriver,这个类名不要写错。URL 里的characterEncoding=utf-8是防止中文乱码的关键,很多人漏了这条导致界面显示问号。1433 是 SQL Server 默认端口,如果你安装实例时改过端口,这里必须同步改。JdbcAdapter 的价值在于全局只此一处维护连接参数,换库换密码只改这一个类。

3. 为什么是 Java + Swing + SqlServer:技术选型的取舍和逻辑

做毕设选技术栈,不是功能越新越好,是越稳越好。这套系统的选型在 2025 年回头看依然很合理,我按实际答辩和使用的角度帮你分析为什么这个组合站得住。

3.1 Swing 的界面开发效率,对比 JavaFX 和 Web 方案的实际差异

Swing 被说老,但它有一个毕设场景最需要的优点:不需要配前端环境,不需要 Node.js,不需要构建工具链,一个 JDK 就能跑图形界面。JavaFX 的 FXML 和 CSS 确实更现代,但学习曲线陡,而且很多学校的实验室电脑 JavaFX 环境没配全,跑起来报一堆模块错误。Web 方案要处理前后端分离、跨域、部署,写一套下来工作量翻倍。

Swing 的组件拖拽配合代码调整,两三天就能把界面框架搭完。这套系统里用到的 JTable 显示成绩数据、JComboBox 选班级年级、JTextField 录入分数,全是 Swing 最成熟的组件,网上资料最多,遇到问题一搜就有答案。答辩时你讲“为什么用 Swing”,一句“能满足桌面教务管理场景的交互需求,部署轻量,JDK 直接运行”就能过关。

3.2 SqlServer 在教务场景的实战优势,为什么不用 MySQL

SqlServer 在很多学生眼里没 MySQL 熟悉,但在这套系统里是合理选择。班级、学生、成绩天然是关系型数据,SqlServer 的图形化管理工具 SSMS 对新手极其友好——备份还原、写 SQL、看查询计划都是可视化操作,比命令行操作 MySQL 更容易上手。

从毕业设计答辩角度看,SqlServer 有一个实际优势:事务处理和约束机制很成熟,存储过程语法丰富。你可以在讲解视频里演示在 SSMS 里建表、建索引、写聚合查询(AVG、SUM 统计平均分总分),这些都是答辩加分项。成绩分析要有说服力,SqlServer 的 T-SQL 在这类报表查询上表达力比 MySQL 更强,写复杂统计语句时不需要绕弯。

3.3 JDBC + SqlServer 的数据链路,数据库连接 URL 参数逐个说明

JDBC 连接 SqlServer 的链路不长,但每一步都有讲究:

// 完整 JDBC 连接串示例 jdbc:sqlserver://127.0.0.1:1433;DatabaseName=StudentDB;characterEncoding=utf-8;loginTimeout=5 // 驱动类 Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); // 建立连接 Connection conn = DriverManager.getConnection(url, "sa", "你的密码");

URL 里每一项都是坑:127.0.0.1是回环地址,如果你用的是 SQL Server Express 命名实例(比如localhost\SQLEXPRESS),1433 端口可能没开,要改成jdbc:sqlserver://localhost\\SQLEXPRESS;DatabaseName=StudentDB这种形式。DatabaseName必须和实际库名一致,不然连接直接失败。loginTimeout=5是让连接尝试 5 秒就超时,避免网络不通时界面卡死。

驱动 jar 的版本也要注意。SqlServer JDBC 驱动从 6.2 版本开始支持 JDBC 4.2,7.x 版本兼容 Java 8 和 9,你装的 JDK 如果是 8,选sqljdbc42.jar或mssql-jdbc-7.x.jre8.jar最稳。千万别用老掉牙的 sqljdbc4.jar 去扛 Java 11 以上的环境,Class 版本冲突会直接抛UnsupportedClassVersionError。

4. 环境搭建与系统部署:从零到跑通的完整步骤

这一章是最容易出现劝退的环节。很多人代码看懂了,卡在环境上——数据库装不上、驱动找不到、连接报错。我把整套部署拆成五步,每一步都给你能直接照抄的命令和参数。

4.1 SQL Server 安装和数据库还原,SSMS 图形化操作的分步说明

4.1.1 SQL Server 安装注意点

我一般建议装 SQL Server 2019 Developer 版或者 Express 版,Developer 功能全,Express 免费且够用——但如果需求里有大表统计,Express 版有 10GB 数据库大小限制,毕设数据量小无所谓,正常开发建议直接装 Developer 版。

安装时认证模式选“混合模式(SQL Server 身份验证 + Windows 身份验证)”,并给 sa 账号设置密码。默认情况刚装完 sa 是禁用的,后面连接会报“用户 sa 登录失败”,这个坑我在避坑章里专门说。

4.1.2 数据库还原操作步骤

拿到项目资源后,里面通常有个.bak文件或.sql脚本。.bak文件用 SSMS 图形化还原:

  1. 打开 SSMS,连接到本地数据库实例,右键“数据库”节点选“还原数据库”
  2. 源设备选择你的.bak文件路径,目标数据库名按项目的库名填写(比如 StudentDB)
  3. 点击确定,看到“已成功还原”提示就完成了

.sql脚本更直接,用 SSMS 打开文件,直接选中全部执行。脚本执行时确认顶部USE DatabaseName的库名和你本地要建的库一致,不一致就先建库再改USE指向。

4.2 JDK 和 IDE 的环境配置,CLASSPATH 与项目导入细节

JDK 版本建议 JDK 8 或 JDK 11,这两个版本对 Swing 的支持最稳定。这些年的实战经验告诉我,JDK 17 跑 Swing 也可以,但有些老代码用了内部 API,JDK 17 模块化后可能访问受限,报IllegalAccessError。毕设资源要求稳,就选 JDK 8,永不过时的组合。

配置环境变量,Windows 系统照这个顺序来:

# 新建 JAVA_HOME 系统变量,指向 JDK 安装目录 JAVA_HOME = C:\Program Files\Java\jdk1.8.0_202 # 修改 Path 变量,追加 %JAVA_HOME%\bin

IDE 选 Eclipse 或 IntelliJ IDEA 都行。导入项目时注意:如果资源里带.classpath和.project文件,直接用 Eclipse 的 Import -> Existing Projects into Workspace;如果只有源代码,就新建 Java 项目,把src目录整个复制进项目源码目录。导入后第一件事是把sqljdbc42.jar加进构建路径——右键项目 -> Build Path -> Configure Build Path -> Add External JARs,选中驱动 jar。

4.3 配置文件修改要点,数据库账号密码与端口按本地环境调整

这套系统的连接参数集中在 JdbcAdapter 类中,你只需要改三处:

private static String url = "jdbc:sqlserver://localhost:1433;DatabaseName=StudentDB;characterEncoding=utf-8"; private static String user = "sa"; private static String password = "123456";

一个常见误区是只改密码不改用户名。如果你本地 SQL Server 没有启用 sa 账号,用 Windows 身份验证登录数据库,把user改成你的 Windows 登录名、密码留空也能连(前提是驱动支持集成验证),但集成验证配置复杂,我的建议是直接启用 sa:

-- 在 SSMS 中执行,启用 sa 并设置密码 ALTER LOGIN sa WITH PASSWORD = '你的强密码'; ALTER LOGIN sa ENABLE;

改完后重新启动 SQL Server 服务(服务名是 MSSQLSERVER),确保新配置生效。

4.4 运行验证清单:登录测试、主窗体跳转与按角色的功能验证

数据库还原好、代码导入好、驱动配好之后,先别急着点运行,按下面的清单验证,省得后面出了问题不知道是哪一层的问题:

  1. 运行JF_login,确认窗口能弹出来,不报ClassNotFoundException
  2. 输入初始账号密码(项目内自带默认账户,通常在讲解视频或 README 里有说明),点击登录
  3. 登录成功后确认主窗体打开,旧窗口隐藏
  4. 进入“成绩录入”,确认班级下拉框能加载出班级数据、学生列表能渲染出来——这一步能验证数据库连接没问题
  5. 随便录入一条成绩,点保存,重新查询确认数据持久化成功

如果第 2 步就报错,说明 JDBC URL、账号密码或者驱动 jar 有问题,按上面的配置检查一遍。94% 的启动失败都在这一步,别急着怀疑代码。

5. 避坑:SqlServer 连接和 Swing 开发的五条血泪经验

这一章是实战里最容易翻车的点和我的处理办法,每条都是真金白银的踩坑记录。

5.1 连接报错:通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败

现象:运行程序时报The TCP/IP connection to the host localhost, port 1433 has failed,日志里跟着Error: "Connection refused"。

原因:SQL Server 的 TCP/IP 协议默认不通。安装时默认把 TCP/IP 协议禁用,或者只开了 Shared Memory,导致外部 JDBC 连不进去。校园网环境下防火墙也会拦 1433。

解决:打开“SQL Server 配置管理器”,找到“SQL Server 网络配置 -> MSSQLSERVER 的协议”,右键 TCP/IP 选择“启用”。然后右键属性,把“IP 地址”标签页里IP1和IPAll的 TCP 端口都改成 1433。重启 SQL Server 服务,再次运行程序。

5.2 ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver

现象:点击运行,控制台直接抛java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver。

原因:驱动 jar 没有进项目的构建路径。Eclipse 里最常见的情况是你把 jar 放进了 lib 文件夹,但没添加到 Build Path,导致编译过、运行时报类找不到。

解决:右键项目 -> Build Path -> Configure Build Path -> Libraries 标签 -> Add External JARs,把sqljdbc42.jar加进去。要确认 jar 在Referenced Libraries节点里显示,才算真正生效。

5.3 登录失败:用户 sa 登录失败,SQL Server 给了名称为空或默认的数据库

现象:连接 URL、驱动都正确,但登录时报错用户 'sa' 登录失败,或者给了名称为空的数据库访问权限。

原因:sqljdbc 连接串里没有指定DatabaseName,导致认证后无法确定默认库,系统把连接当成“master 库下以游客身份访问”,权限被拒绝。另一种更常见的情况是 sa 密码策略太强(强制密码过期导致 sa 被锁)。

解决:URL 里明确加DatabaseName=StudentDB,不要漏掉。如果 sa 被锁定,SSMS 里执行ALTER LOGIN sa WITH CHECK_POLICY = OFF;关闭强制密码策略,再重新设置密码。改完必须重启 SQL Server 服务。

5.4 中文乱码:界面上的学生姓名变成一串问号

现象:数据库里的中文在 JTable 里渲染成????,或者从输入框写入数据库后读出来是乱码。

原因:JDBC URL 里没有characterEncoding=utf-8,驱动用了系统默认字符集去编码,和数据库的排序规则对不上。另一个原因是数据库建库时的排序规则选择不当(比如用了 Latin1_General,对应的 nvarchar 字段没配对)。

解决:URL 里加characterEncoding=utf-8。还要检查数据库字段类型:中文必须用nvarchar而非varchar,用varchar存中文在 SQL Server 里是灾难。建表 SQL 改字段类型后再插入数据,完美解决。

5.5 Swing 界面运行卡死:点击按钮后窗口无响应,CPU 占用飙升

现象:点“查询成绩”后界面直接卡住,鼠标转圈,好几秒甚至十几秒才恢复,数据量稍大直接卡死。

原因:你把数据库查询操作直接放在了界面线程(Event Dispatch Thread)里。JDBC 查询和网络 IO 都阻塞在 EDT 上,界面就无法重绘,表现出来就是卡死。这套代码的查询模块如果数据量变大,也会遇到同样问题。

解决:把耗时查询放进独立线程:

new Thread(() -> { // JDBC 查询逻辑,放到后台线程执行 List<StudentScore> list = ScoreDao.queryByClass(className); // 查询完成后回到界面线程更新表格 SwingUtilities.invokeLater(() -> { // 更新 JTable 模型 }); }).start();

这算是从“能跑”到“跑得好”的进阶优化。毕设答辩时提一句“这里做了线程分离,避免查询阻塞界面”,是很有分量的加分点。从那以后我每次提到多线程刷新界面,都强制先确认是否用了SwingUtilities.invokeLater回到 EDT 更新组件,这能省下大量调试烂界面的时间。

6. 进阶用法:给成绩管理系统加一个报表导出功能,用不到 200 行代码

项目跑通之后,你手里的东西已经能交差了。但如果你想在答辩时拿出点不一样的东西,或者在真实使用场景里帮班主任省时间,我给你一个值得加的进阶功能:把成绩汇总查询导出成 HTML 报表,浏览器直接打开就能打印。这比在 Swing 里调打印 API 简单得多,而且效果直观。

工作原理很简单:成绩数据从数据库查出来后,拼成一张 HTML 表格,加上汇总统计行(平均分、及格率),保存成.html文件,用默认浏览器打开,班主任直接 Ctrl+P 打印。HTML 表格的样式控制比 Swing 的 JTextPane 容易得多,也避开了 POI 生成 Word 图表的重型依赖。

// 导出成绩单为 HTML 报表的核心方法 public void exportGradeReport(List<StudentScore> list, String filePath) { StringBuilder sb = new StringBuilder(); sb.append("<!DOCTYPE html><html><head><meta charset='utf-8'>"); sb.append("<style>table{border-collapse:collapse;width:100%}"); sb.append("th,td{border:1px solid #333;padding:8px;text-align:center}"); sb.append("</style></head><body>"); sb.append("<h2>班级成绩汇总表</h2>"); sb.append("<table><tr><th>学号</th><th>姓名</th><th>语文</th><th>数学</th><th>英语</th><th>总分</th><th>平均分</th></tr>"); double totalScore = 0; for (StudentScore s : list) { double sum = s.getChinese() + s.getMath() + s.getEnglish(); double avg = sum / 3; totalScore += sum; sb.append("<tr>") .append("<td>").append(s.getStudentNo()).append("</td>") .append("<td>").append(s.getStudentName()).append("</td>") .append("<td>").append(s.getChinese()).append("</td>") .append("<td>").append(s.getMath()).append("</td>") .append("<td>").append(s.getEnglish()).append("</td>") .append("<td>").append(sum).append("</td>") .append("<td>").append(String.format("%.1f", avg)).append("</td>") .append("</tr>"); } String totalAvg = String.format("%.1f", totalScore / list.size() / 3); sb.append("<tr><td colspan='5'>全班平均分</td><td colspan='2'>").append(totalAvg).append("</td></tr>"); sb.append("</table></body></html>"); try (FileWriter fw = new FileWriter(filePath)) { fw.write(sb.toString()); Desktop.getDesktop().browse(new File(filePath).toURI()); } catch (IOException e) { e.printStackTrace(); } }

这个方法的看点有三个。参数list是查询到的成绩集合,filePath是导出路径,两者都由调用方传入。String.format("%.1f", avg)保证平均分只显示一位小数,报表好读。Desktop.getDesktop().browse()是 Java 自带的调用系统默认浏览器方式,不需要额外依赖。对于毕设来说,这段代码放到“扩展功能”里讲,立刻就和只会增删改查的拉开差距。

给班主任用还有一个贴心细节:文件名带日期后缀,方便归档。我一般会在调用时拼上系统日期:

String fileName = "班级成绩_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".html"; exportGradeReport(list, "D:/reports/" + fileName);

这套系统的扩展空间其实不小——成绩分析可以加标准差和排名,导出可以加 Excel 格式,登录可以加验证码。这些都建立在跑通基础版本之后。那以后我每次拿到一套新项目,都会强制自己先跑通原版再做扩展,把“能跑”和“会改”分开练。改坏了有大把时间对比原版找回状态,这习惯帮我避过很多次自我毁灭级调试。希望这套学生成绩管理系统能让你少踩几个坑,把有限的时间花在真正能提升能力的地方——能跑通、能讲明白、能改出新功能,这才是下载一份源码最实在的收获。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询