ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Java Swing+SqlServer学生成绩管理系统:毕业设计实现与避坑指南

Java Swing+SqlServer学生成绩管理系统:毕业设计实现与避坑指南 简介这是一套面向计算机相关专业毕业设计场景的JavaSwingSqlServer学生成绩管理系统完整项目解决教师对学生成绩录入、统计、分析与打印展示的需求。系统覆盖成绩管理、班级/学生/教师维护、综合查询等常见模块前端采用Swing图形界面后端配合SqlServer数据库结构清晰适合作为课程设计或毕设参考。压缩包共176个文件包含31个java源文件、104个class编译产物、SqlServer数据库文件mdf/ldf、10个mp4讲解视频和16个gif操作演示另附jar包及工程配置文件总大小约183MB。目前已有187人学习浏览可帮助使用者快速了解运行配置与开发思路。配套视频讲解、可直接导入的源码与数据库既能支撑二次开发和功能扩展也便于在答辩中展示完整实现过程。1. 用 JavaSwingSqlServer 做学生成绩管理系统为什么这套老技术栈在毕业设计里反而最稳如果你在网上搜“学生成绩管理系统源代码”十套里有七八套是 JavaSwingSqlServer 的组合。Swing 是 Java 自带的桌面 UI 框架SqlServer 是微软的关系型数据库两样东西放在今天都算不上时髦但作为毕业设计选题它几乎把 Java 基础阶段该考的点全占了JDBC 数据库访问、面向对象设计、GUI 事件模型、SQL 写表与联表查询。对多数本科生来说这个项目比 Spring Boot 后端加 Vue 前端的方案更容易讲清楚也更容易在答辩时当场跑通。很多人觉得 Swing 太老想换成 JavaFX 或干脆做成网页版结果反而被 Maven 依赖、前端路由和跨域问题拖住进度。我的建议是毕业设计以稳妥交付为第一目标。这套系统真正的难点不在 Swing 本身而在数据库连接配置、中文乱码、表格数据刷新这三类问题上。下文按我从环境搭建到交付演示的完整顺序讲每段代码都可以直接抄进你的项目里改。2. 从建库到连库先把 SqlServer 的库建好再让 Java 代码按 JDBC 协议去访问它2.1 JDK 8 与 SQL Server 2019 Express毕业设计选型不追求新追求不翻车做这个项目我建议环境固定在 JDK 8 加 SQL Server 2019 Express 上。JDK 8 不是最老的可用版本却是 Swing 兼容性最好、网上资料最多的版本SQL Server Express 是微软官方的免费版功能足够单机演示安装包也比企业版小很多。你能在 SqlServer 安装教程和 SqlServer 安装包相关的搜索里找到大量现成步骤但有一条值得先强调Express 版默认实例名是SQLEXPRESS连接串里写localhost:1433连不上得写localhost\\SQLEXPRESS或者用小写实例名。这是新手在这个项目里遇见的第一个坑。开发工具我一般用 IntelliJ IDEA用 Maven 建普通 Java 项目不引入 Spring保持代码结构足够简单。驱动依赖用微软官方提供的 mssql-jdbc 包注意版本必须和 JDK 匹配——JRE 8 对应 9.4.x 或 10.2.x不要贸然用 12.x 以上版本新版驱动对 TLS 握手的要求更严在老旧实验室机器上容易报 SSL 错误。dependency groupIdcom.microsoft.sqlserver/groupId artifactIdmssql-jdbc/artifactId version9.4.1.jre8/version scopecompile/scope /dependency依赖配好后不要急着写代码先确认 SQL Server 服务真的能在 1433 端口上接受 TCP 连接。检查方式很简单在搜索栏打开 SQL Server 配置管理器展开SQL Server 网络配置找到实例对应的协议看 TCP/IP 是否处于已启用状态。默认情况下这东西是禁用的不打开它Java 程序永远报连接被拒。2.2 用 T-SQL 建三张表学生、课程、成绩外键要建在成绩表上成绩管理系统的表结构非常固定常见做法是三张表学生表、课程表、成绩表。学生表主键是学号课程表主键是课程号成绩表用自己的自增 ID 做主键同时把学号和课程号作为外键关联另外两张表。这样设计的好处是成绩表可以随意增删记录不会因为某个学生选了多门课而破坏第一范式。CREATE DATABASE StudentScoreDB; GO USE StudentScoreDB; GO CREATE TABLE Student ( student_no VARCHAR(12) PRIMARY KEY, student_name NVARCHAR(50) NOT NULL, class_name NVARCHAR(50), sex NCHAR(1) DEFAULT N男 ); CREATE TABLE Course ( course_no VARCHAR(10) PRIMARY KEY, course_name NVARCHAR(50) NOT NULL, credit DECIMAL(3,1) ); CREATE TABLE Score ( id INT IDENTITY(1,1) PRIMARY KEY, student_no VARCHAR(12) NOT NULL, course_no VARCHAR(10) NOT NULL, score DECIMAL(5,2), exam_time DATE, FOREIGN KEY (student_no) REFERENCES Student(student_no), FOREIGN KEY (course_no) REFERENCES Course(course_no) );注意这段 SQL 里所有中文字段默认值前面都加了N前缀比如N男。在 SQL Server 里N代表 Unicode 字符串不加N中文字符在简体中文排序规则下可能没问题但换到英文实例或繁体环境下就会变成乱码。成绩字段用DECIMAL(5,2)允许存 999.99 以内的分数既支持百分制也支持带小数点的绩点。2.3 写 DBUtil 连接工具把驱动加载、连接获取、资源释放统一收口每个需要数据库操作的类都写一遍DriverManager.getConnection()会让代码变得很散。常见做法是抽一个DBUtil类把连接信息放在静态常量里所有业务代码统一从DBUtil拿连接。这里有个小技巧连接串末尾的encryptfalse必须写SQL Server 2019 默认强制加密连接而 JDK 8 自带的加密协议不一定能通过握手加上这个参数可以省掉一堆 TLS 报错。import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class DBUtil { private static final String URL jdbc:sqlserver://localhost:1433;databaseNameStudentScoreDB;encryptfalse; private static final String USER sa; private static final String PASSWORD 123456; static { try { Class.forName(com.microsoft.sqlserver.jdbc.SQLServerDriver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } public static void close(Connection conn, Statement stmt, ResultSet rs) { if (rs ! null) { try { rs.close(); } catch (SQLException ignored) {} } if (stmt ! null) { try { stmt.close(); } catch (SQLException ignored) {} } if (conn ! null) { try { conn.close(); } catch (SQLException ignored) {} } } }这段代码里的Class.forName在 JDBC 4.0 之后其实可以省略驱动包通过 SPI 机制自动注册但保留下来有个好处如果驱动包没加载成功报错会发生在这一行你能第一时间判断是依赖没下全还是版本冲突。close方法设计成三级释放顺序是先 ResultSet 再 Statement 最后 Connection避免直接关连接时还有未读完的游标数据。3. 用 Swing 做界面JTable 展示数据、JDialog 收集表单、事件监听触发增删改3.1 用 JTable 加 DefaultTableModel 把 ResultSet 显示成中文成绩表Swing 里展示数据库查询结果最直接的方式是 JTable 套 DefaultTableModel。直接把 ResultSet 遍历后逐行addRow到模型里模型再交给界面显示。之所以不用 JTable 自带的setValueAt去做编辑是为了把界面显示和数据库操作隔离开——界面上改的只是内存里的模型点保存按钮时才触发 UPDATE 语句。import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.sql.*; public class ScoreTablePanel extends JPanel { private JTable table; private DefaultTableModel model; public ScoreTablePanel() { String[] columns {学号, 姓名, 班级, 课程, 成绩, 考试时间}; model new DefaultTableModel(columns, 0); table new JTable(model); table.setFillsViewportHeight(true); add(new JScrollPane(table)); refreshTable(); } public void refreshTable() { model.setRowCount(0); String sql SELECT s.student_no, s.student_name, s.class_name, c.course_name, sc.score, sc.exam_time FROM Score sc JOIN Student s ON sc.student_no s.student_no JOIN Course c ON sc.course_no c.course_no; try (Connection conn DBUtil.getConnection(); Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery(sql)) { while (rs.next()) { model.addRow(new Object[]{ rs.getString(student_no), rs.getString(student_name), rs.getString(class_name), rs.getString(course_name), rs.getBigDecimal(score), rs.getDate(exam_time) }); } } catch (SQLException e) { JOptionPane.showMessageDialog(this, 查询失败 e.getMessage()); } } }这段查询语句没有用SELECT *而是把三张表 JOIN 起来直接返回页面要展示的字段。注意JOIN的顺序先写成绩表主表再 LEFT JOIN 学生表和课程表这样即使某个学生有成绩但学生记录被误删这条成绩记录也不会从界面上消失。try-with-resources写法让连接、语句、结果集都自动关闭比手动 finally 块简洁得多。3.2 把新增和修改做成同一个 JDialog用一个标志位区分两种模式学生成绩管理系统的录入界面通常长这样上半部分是一个表格下半部分是一个按钮栏点添加弹出一个带输入框的对话框点修改也弹一样的对话框只是把当前选中行的数据预先填进去。这个对话框不需要写两个类用一个int mode标志位就能区分0 表示新增1 表示修改。import javax.swing.*; import java.awt.*; import java.sql.*; public class ScoreEditDialog extends JDialog { private JTextField studentNoField new JTextField(12); private JTextField courseNoField new JTextField(12); private JTextField scoreField new JTextField(12); private int mode; private int editId; public ScoreEditDialog(Frame owner, int mode, Object[] rowData) { super(owner, mode 0 ? 新增成绩 : 修改成绩, true); this.mode mode; if (mode 1 rowData ! null) { this.editId Integer.parseInt(rowData[5].toString()); } setLayout(new GridLayout(3, 2, 8, 8)); add(new JLabel(学号)); add(studentNoField); add(new JLabel(课程号)); add(courseNoField); add(new JLabel(成绩)); add(scoreField); JButton okBtn new JButton(保存); okBtn.addActionListener(e - saveScore()); add(okBtn); setSize(280, 180); setLocationRelativeTo(owner); } private void saveScore() { // 持久化逻辑见下段 } }rowData数组直接来自表格当前选中行的getValueAt遍历结果注意表格显示给用户看的是课程名称但外键存储需要的是课程号所以要么在表格模型里隐藏一列课程号要么在打开对话框时单独根据课程名称再查一次数据库。我一般推荐后者逻辑更直白课上讲解时也更符合先查再改的思路。3.3 成绩统计不写在 UI 线程用核心查询方法把平均分、不及格人数一次算清成绩统计是这个系统的灵魂功能。最简单的实现是算平均分、最高分、最低分、不及格人数四个指标。但别在按钮的事件回调里直接写 SQL应该把统计逻辑放进一个独立的ScoreService类界面只调用方法获取字符串结果。这样老师提问时可以清晰地说出界面层只管展示数据层管查询。public class ScoreService { public String calcCourseStats(String courseNo) { String sql SELECT COUNT(*) AS total, AVG(score) AS avg_score, MAX(score) AS max_score, MIN(score) AS min_score, SUM(CASE WHEN score 60 THEN 1 ELSE 0 END) AS fail_cnt FROM Score WHERE course_no ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, courseNo); try (ResultSet rs ps.executeQuery()) { if (rs.next()) { return String.format(总人数 %d平均分 %.2f最高 %.2f最低 %.2f不及格 %d 人, rs.getInt(total), rs.getBigDecimal(avg_score), rs.getBigDecimal(max_score), rs.getBigDecimal(min_score), rs.getInt(fail_cnt)); } } } catch (SQLException e) { e.printStackTrace(); } return 暂无数据; } }SUM(CASE WHEN score 60 THEN 1 ELSE 0 END)是 SQL Server 里做条件计数最常用的写法功能等同于COUNT_IF但兼容性更好。平均分用AVG函数返回 DECIMAL 类型拿到 Java 侧用BigDecimal接收比Double更精确避免浮点误差。这里的查询必须用PreparedStatement而不是拼字符串courseNo来自用户在界面上的输入框直接拼接有 SQL 注入风险——答辩时老师常拿这一点试探学生。4. 避坑指南五个让 Swing 加 SqlServer 项目当场翻车的老问题4.1 连接被拒SQL Server 配置管理器里 TCP/IP 协议默认是关闭的现象是 Java 程序一启动就报Cannot connect to localhost:1433服务名能看到ping 也能通但 JDBC 就是连不上。原因几乎都是 SQL Server 的 TCP/IP 协议没有启用默认配置下 SQL Server 只允许本机使用命名管道通信外部程序包括 Java 的 JDBC 驱动都无法访问。解决方法是去 SQL Server 配置管理器中找到SQL Server 网络配置右键 TCP/IP 选择启用然后重启 SQL Server 服务。这个操作不影响已经建好的数据库可以放心释放。4.2用户 sa 登录失败身份验证模式默认不放开远程账号用sa账号连数据库报错Login failed for user sa. (Microsoft SQL Server, Error: 18456)新手会以为是密码错了反复改密码也没用。真正原因是 SQL Server 安装时选了 Windows 身份验证模式这个模式下sa账号被禁用数据库只认系统用户。解决步骤用 Windows 身份验证登录 SSMS右键服务实例选择属性在安全性页面把服务器身份验证改为SQL Server 和 Windows 身份验证模式然后执行ALTER LOGIN sa WITH PASSWORD 新密码, CHECK_POLICY OFF;创建可用的密码。改完记得重启 SQL Server 服务才能生效。4.3 中文全部变成问号连接串、表字段的排序规则、Swing 字体三层都要查界面上显示的中文正常但写入数据库后再查出来全是???或者反过来数据库里有中文Java 界面读出来是乱码。这个问题的排查要按三层来第一层是 JDBC 连接串确认 URL 里写了encryptfalse并且没有多余的编码参数第二层是表结构SQL Server 里的VARCHAR不是 Unicode 类型存中文必须用NVARCHAR建表时写入N前缀第三层是 Swing 本身Windows 下默认字体能显示中文如果部署到 Linux 服务器上需要手动设置Font(SansSerif, Font.PLAIN, 14)。我的数据库相关字段前面全部加N前缀建表DBUtil 连接串固定不变从未在中文上出过问题。4.4 增删改操作成功但表格不动内存里的 TableModel 没同步客户端刷新失效点击新增按钮后数据库里确实多了一行用 SSMS 查得到但 Swing 表格界面纹丝不动。这不是数据库问题是你忘了在保存操作完成后调用refreshTable()。保存成功的标志不只是执行 SQL 不报错还要重新查一遍数据并覆盖 TableModel。我见过不少同学把refreshTable()写在插入 SQL 之前结果先刷新再插入操作结束界面依然旧数据。代码里务必在JOptionPane.showMessageDialog提示保存成功之后、对话框关闭之前调用刷新方法。4.5 SqlServer 字符串转数字报错成绩字段建表时选错类型数据导完才后悔成绩列用VARCHAR存储查询统计时AVG(score)报错Error converting data type varchar to numeric。原因是在建表阶段图省事把 score 定义成文本类型等录入了大量数据后再想改用DECIMAL如果里面混入非数字字符ALTER TABLE 会直接失败。解决方法是使用TRY_CONVERT定位脏数据SELECT * FROM Score WHERE TRY_CONVERT(DECIMAL(5,2), score) IS NULL把所有非数字行清掉或修正后执行 ALTER 语句。如果数据量确实很大且不想手工改就把这张表复制一份重新建但要注意外键关系会一起变乱。5. 交付物与演示视频源代码之外毕业设计真正该打包的是这三样5.1 把数据库备份成 .bak 文件并附带还原步骤裸 SQL 脚本容易在老师机器上失败很多同学交作业只交一份 SQL 脚本让老师自己执行建库。但脚本在 Windows 中文环境和 Linux 环境下编码不一致老师机器上的 SQL Server 版本排序规则也可能不同脚本跑到一半报错非常尴尬。常见的做法是把整个数据库备份成一个.bak文件老师那边用一条还原命令就能完整恢复所有数据和约束。我在项目里保留了一个restore.sql文件内容只有三行放在压缩包根目录RESTORE DATABASE StudentScoreDB FROM DISK C:\毕业设计备份\StudentScoreDB.bak WITH REPLACE, MOVE StudentScoreDB TO C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA\StudentScoreDB.mdf, MOVE StudentScoreDB_log TO C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA\StudentScoreDB_log.ldf;WITH REPLACE是后悔药老师的机器上已经存在同名数据库时不会报错。路径里的 MOVE 参数要按实际 SQL Server 数据目录改否则还原会失败。访问这里会遇到 SqlServer 配置管理器相关的一个高频问题如果老师机器上默认实例名不是 MSSQLSERVER需要把路径里的实例名一并改掉。5.2 录制 10 分钟讲解视频别从HelloWorld开始从核心业务的闭环开始讲解视频录制时先演示系统运行效果打开程序输入一条成绩记录表格刷新并在统计栏显示最新的平均分和不及格人数。然后切到 IDEA 里讲代码按三层线索走DBUtil 的连接管理、ScoreService 的统计 SQL、界面的事件监听。不要超过 12 分钟老师不会看完 30 分钟的视频。视频里要出现新增一条成绩后表格自动刷新这个镜头这是评审最关注的动态效果。如果你用了 POI 导出 Excel 的功能也可以展示一下这属于加分项。5.3 继续往系统里加东西POI 导出 Excel、图表展示和一套轻量参数约定做完基础版之后可以考虑用 Apache POI 把成绩列表导出成 Excel 表格。常见的期望是Java POI Word 能生成图表吗答案是导出 Excel 更顺手POI 在 Word 里画图表的 API 特别绕Excel 的生成效率和兼容性最好。另外可以在成绩统计区域加一个简单的柱状图不要自己用 Graphics 画引入 JFreeChart 依赖十分钟就能出一个及格率分布图。这个功能不复杂但在答辩里能明显提升项目上限。数据库连接参数我习惯统一维护在一个config.properties文件里不写死在代码里。这样老师的机器如果改过密码只需要改配置文件而不用重新编译。最后说一句我自己带毕设的血泪经验永远不要在答辩当天早上才做环境复测提前三天换一台干净电脑从头安装一遍 SQL Server 和 JDK你会发现那些你以为吃透了的步骤在另一台机器上分分钟翻车。把交付物做成数据库备份 完整源码 演示视频三件套每个文件都用 ASCII 文件名命名避免压缩包解压后乱码。希望这套做法帮到你顺着这条路径走这个题目能稳稳拿下。本文还有配套的精品资源点击获取
返回列表