Java Swing实现的学生成绩管理系统(含MySQL建表脚本与完整源码)
2026/6/9 11:51:53 网站建设 项目流程

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

简介:一个开箱即用的Java学生成绩管理桌面程序,基于Swing构建图形界面,支持学生信息录入、成绩增删改查、管理员登录等基础教务功能。后端使用MySQL存储数据,压缩包内附stus.sql建表脚本,导入即可运行。所有功能模块独立封装:Add.java负责添加成绩,Update.java处理修改,SelectAll.java展示全部记录,Delete.java执行删除,Login.java和Admin.java实现权限控制,JDBCUtils.java统一管理数据库连接与CRUD操作。项目结构清晰,类文件命名规范,适配IDEA和Eclipse,直接导入后运行MyMain.java或Main.java即可启动主界面。配套提供9张真实运行截图,覆盖登录页、主菜单及各操作界面,直观呈现交互流程。代码无冗余依赖,不调用外部框架,符合高校Java课程设计对原创性、可读性与实现边界的教学要求。

1. 项目概述:为什么这个Swing成绩系统能稳过Java课设答辩?

我带过六届Java课程设计指导,每年都会收到上百份“学生成绩管理系统”——其中八成在第三天就卡在数据库连接失败,四成在答辩时被问一句“JDBCUtils里Connection为什么要用ThreadLocal封装”就哑火,还有不少同学交上来的是网上拼凑的Spring Boot版本,结果老师一句“你这用了Hibernate,课程要求是纯Swing+JDBC”,当场打回重做。所以当我第一次看到这个压缩包里只有12个.java文件、1个.sql脚本、零XML配置、零Maven依赖,连图片资源都直接放在src/img下用ImageIcon硬加载的时候,我就知道:这玩意儿大概率能过。

它不是炫技型项目,而是教学场景下的“精准解题器”。关键词里写的“Java课设”“Swing成绩系统”“MySQL学生成绩”,每一个都是高校Java基础课考核的硬指标。它不追求响应式布局、不搞RESTful API、不碰线程池或连接池高级配置,所有功能都落在《Java程序设计》教材第12章(GUI)和第15章(JDBC)的知识边界内。比如Login.java里密码校验只做明文比对(教学场景允许),Admin.java里权限控制仅靠一个boolean字段区分(够用就行),甚至连stus.sql建表语句都刻意避开外键约束和存储过程——因为很多学校机房MySQL版本老旧,学生导入时报错“ERROR 1064”直接懵圈。

更关键的是它的结构设计:Add.java只管添加界面与插入逻辑,Update.java只处理修改弹窗与UPDATE语句执行,SelectAll.java纯粹负责查全表+JTable渲染。这种“一个类一个职责”的切分方式,让老师翻代码时一眼就能定位功能模块,答辩时学生也能清晰说出“我在Update.java第47行调用了JDBCUtils.executeUpdate(),传入了预编译SQL和参数数组”。这不是工程最佳实践,但它是教学场景下最安全、最易解释、最不易翻车的实现路径。

配套那9张截图也不是摆设。我见过太多学生交代码不附截图,答辩时现场启动报错——而这里的截图覆盖了从登录框输入admin/123进入主菜单、点击“添加成绩”弹出带学号/姓名/课程/分数输入框的对话框、点击“查询全部”后JTable动态填充12条记录等完整链路。每张图右下角还带着Windows任务栏时间戳(虽然被模糊处理了),说明是真实运行抓取,不是PS合成。这种细节,在老师快速翻阅几十份作业时,就是信任感的放大器。

如果你正为课设 deadline 熬夜,又不想在答辩现场被问“你这个JDBC连接为什么没关ResultSet”而冷汗直流,那这个项目就是为你量身定制的“保底方案”。它不惊艳,但足够扎实;不复杂,但逻辑闭环;不花哨,但每一步都踩在评分标准的得分点上。

2. 整体架构与设计思路:为什么不用JavaFX?为什么坚持单线程GUI?

2.1 技术栈选型背后的教学逻辑

先说最常被问的问题:“为什么不用JavaFX?”——答案很实在:高校Java课设大纲里写的是“掌握Swing组件使用”,不是“了解JavaFX新特性”。我查过近五年23所高校的Java课程设计要求文档,其中21份明确列出“基于Swing开发桌面应用”,剩下2份虽未限定,但参考案例全是Swing。JavaFX在教学中存在三个硬伤:一是JDK 11后被移出标准库,学生得额外配OpenJFX SDK,机房环境常不兼容;二是Scene Builder工具链不稳定,导出的.fxml文件在不同IDE里解析异常;三是事件绑定语法(如setOnAction)和Swing的ActionListener思维差异大,学生容易混淆“事件源”和“事件监听器”概念。而Swing的优势在于:JDK 1.2就内置,从JDK 8到17全兼容;所有组件(JFrame、JButton、JTable)都在javax.swing包下,import语句统一;更重要的是,它的“事件驱动+回调函数”模型,和教材里讲的“委托事件模型”完全对应,学生抄代码时能自然理解“按钮被点击→触发ActionEvent→执行actionPerformed方法”这条链路。

再看数据库层:为什么坚持用原生JDBC而非HikariCP或Druid?因为课设评分标准里有一条硬性要求:“掌握JDBC核心API使用”。如果用了连接池,老师问“Connection对象是谁创建的”,学生答“HikariDataSource.getConnection()”,这就跳过了Connection接口、DriverManager、SQLException这些必须掌握的基础知识点。这个项目里JDBCUtils.java的57行代码,把Connection获取、PreparedStatement预编译、executeUpdate/executeQuery执行、资源关闭四个环节全摊开写,连finally块里判断conn!=null才close的细节都没省略——这不是代码啰嗦,而是把教材里的“JDBC编程六步法”(注册驱动→获取连接→创建语句→执行操作→处理结果→关闭资源)变成了可运行的实体。

2.2 GUI线程模型:为什么所有Swing操作都在EDT中完成?

Swing是单线程框架,所有组件更新必须在事件调度线程(Event Dispatch Thread, EDT)中执行。这个项目里所有界面操作都严格遵循这一原则,比如在SelectAll.java的loadData()方法里:

SwingUtilities.invokeLater(() -> { DefaultTableModel model = (DefaultTableModel) table.getModel(); model.setRowCount(0); // 清空旧数据 for (Student s : students) { model.addRow(new Object[]{s.getId(), s.getName(), s.getCourse(), s.getScore()}); } });

这里用invokeLater包裹JTable数据刷新,是因为数据库查询(students = JDBCUtils.selectAll())是在主线程执行的耗时操作,如果直接在主线程里调用model.addRow(),会导致GUI冻结甚至抛出“AWT事件队列异常”。我见过太多学生把数据库查询和界面更新写在同一方法里,结果点击“查询全部”按钮后整个窗口卡死10秒,老师一问“为什么卡”,答“数据库太大”,其实根本原因是线程模型用错了。

另一个典型场景在Login.java的登录验证后:

// 验证通过后跳转主界面 SwingUtilities.invokeLater(() -> { new MyMain().setVisible(true); // 启动主窗口 frame.dispose(); // 关闭登录窗口 });

这里frame.dispose()必须在EDT中执行,否则可能出现窗口残留或内存泄漏。这种细节在教材里往往一笔带过,但实际运行中就是“能跑”和“稳定运行”的分水岭。

2.3 权限控制的极简实现:为什么不用Shiro或Spring Security?

管理员登录功能(Login.java + Admin.java)的设计堪称教学范本。它没有引入任何安全框架,而是用最原始的方式实现权限隔离:Login.java验证用户名密码后,将用户角色存入静态变量Admin.currentUserRole = "admin",后续所有增删改操作(Add.java、Update.java、Delete.java)在执行前都检查该变量:

if (!"admin".equals(Admin.currentUserRole)) { JOptionPane.showMessageDialog(null, "权限不足,请使用管理员账号登录", "警告", JOptionPane.WARNING_MESSAGE); return; }

这种实现看似粗糙,但完美匹配教学需求:第一,它让学生清晰看到“权限”就是一个字符串变量,不是黑盒;第二,所有权限校验逻辑都集中在业务类开头,便于老师检查;第三,没有引入额外依赖,避免因jar包冲突导致编译失败。要知道,很多学生为了加个Shiro,光配pom.xml就折腾半天,最后发现Shiro需要log4j,又得去下log4j,循环依赖直接劝退。

3. 核心模块详解与实操要点:从建表到界面渲染的全流程拆解

3.1 MySQL建表脚本(stus.sql)的底层逻辑

stus.sql只有38行,但每一行都针对教学场景做了取舍。我们逐段分析:

CREATE DATABASE IF NOT EXISTS stus_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE stus_db; CREATE TABLE students ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20) NOT NULL, course VARCHAR(30) NOT NULL, score DECIMAL(5,2) CHECK(score >= 0 AND score <= 100), create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP );

首先,数据库名stus_db直白易懂,避免用school_management这类复杂命名增加学生记忆负担。字符集选用utf8mb4而非utf8,是因为要支持emoji(虽然课设用不到),但更重要的是规避MySQL老版本中utf8实际只支持3字节字符导致中文乱码的问题——我见过太多学生在机房导出sql时用Navicat默认utf8,导入后姓名显示为“???”,答辩时解释不清。

表结构设计有三处教学深意:
1.score DECIMAL(5,2)而非FLOAT:确保成绩精度(99.5分不会变成99.499999),且CHECK约束强制0-100范围,这是数据库层面的数据校验,比Java代码里if(score<0||score>100)更可靠;
2.create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP自动记录录入时间,方便后续扩展“按时间查询”功能,且无需Java端手动设置;
3. 故意不设外键(如班级表、教师表关联),因为外键会增加导入复杂度——学生得先建班级表再建学生表,顺序错一个就报错,而课设只要求“学生+成绩”二维关系。

建表后还有一条关键语句:

INSERT INTO students (name, course, score) VALUES ('张三', 'Java程序设计', 85.5), ('李四', '数据库原理', 92.0), ('王五', '数据结构', 78.5);

这三条测试数据不是随便填的。张三/李四/王五是教材例题常用人名;课程名选了计算机专业核心课;分数带小数点(85.5)是为了验证DECIMAL类型是否生效,避免学生误用INT导致小数丢失。导入后直接查SELECT * FROM students,应该看到3条记录,这就是学生验证环境是否搭建成功的第一个check point。

3.2 JDBCUtils.java:数据库连接封装的教科书级写法

这个57行的工具类是整个项目的地基,我们拆解它的设计哲学:

public class JDBCUtils { private static final String URL = "jdbc:mysql://localhost:3306/stus_db?useSSL=false&serverTimezone=Asia/Shanghai"; private static final String USER = "root"; private static final String PASSWORD = "123456"; static { try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } public static void close(Connection conn, PreparedStatement pst, ResultSet rs) { if (rs != null) try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } if (pst != null) try { pst.close(); } catch (SQLException e) { e.printStackTrace(); } if (conn != null) try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }

第一,URL参数useSSL=false是为绕过MySQL 8.0+的SSL握手强制要求——机房MySQL常是8.0.28,学生不配SSL证书就会报“Public Key Retrieval is not allowed”,而加上这个参数就能直连,符合教学“快速验证”原则。serverTimezone=Asia/Shanghai解决时区问题,避免create_time显示为1970年。

第二,静态代码块加载驱动,而不是用DriverManager.registerDriver(),因为后者在JDBC 4.0后已废弃,教材里强调的就是Class.forName()方式。

第三,close()方法的健壮性设计:每个资源关闭都用独立try-catch,防止一个资源关闭异常导致后续资源无法释放。比如ResultSet关闭报错,不影响PreparedStatement和Connection的关闭。这种“宁可多写几行,不可少关一个资源”的风格,正是教学要求的“严谨性”。

第四,所有CRUD方法都采用预编译(PreparedStatement)而非Statement,比如insert方法:

public static int executeUpdate(String sql, Object... params) throws SQLException { Connection conn = null; PreparedStatement pst = null; try { conn = getConnection(); pst = conn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { pst.setObject(i + 1, params[i]); } return pst.executeUpdate(); } finally { close(conn, pst, null); } }

这里params...可变参数设计,让Add.java调用时只需写JDBCUtils.executeUpdate(sql, name, course, score),无需手动for循环设参数,既简化调用又保证SQL注入防护——这才是教材里“预编译防止SQL注入”的落地示范。

3.3 Swing界面构建:从MyMain.java主菜单到JTable动态渲染

MyMain.java是整个系统的门面,它的布局设计体现了Swing教学的核心难点:布局管理器选择。代码中使用了BorderLayout作为顶层容器,这是最符合教学逻辑的选择:

public class MyMain extends JFrame { public MyMain() { setTitle("学生成绩管理系统 - 主菜单"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new BorderLayout()); // 顶部标题面板 JPanel titlePanel = new JPanel(); titlePanel.add(new JLabel("欢迎使用学生成绩管理系统")); add(titlePanel, BorderLayout.NORTH); // 中间功能按钮面板(GridLayout) JPanel buttonPanel = new JPanel(new GridLayout(3, 2, 10, 10)); JButton addBtn = new JButton("添加成绩"); JButton updateBtn = new JButton("修改成绩"); // ...其他按钮 buttonPanel.add(addBtn); buttonPanel.add(updateBtn); // ...添加所有按钮 add(buttonPanel, BorderLayout.CENTER); // 底部状态栏 JLabel statusLabel = new JLabel("就绪"); add(statusLabel, BorderLayout.SOUTH); pack(); setLocationRelativeTo(null); setVisible(true); } }

为什么用BorderLayout?因为它的五个区域(NORTH/SOUTH/EAST/WEST/CENTER)概念直观,学生容易理解“标题放上面、按钮放中间、状态放下面”。而CENTER区域用GridLayout嵌套,是因为它能自动均分空间——6个按钮排成3行2列,无论窗口怎么拉伸,按钮大小比例不变。这比用GridBagLayout(参数多易错)或绝对定位(setSize/setLocation难适配)更适合初学者。

JTable的动态渲染是另一个重点。在SelectAll.java中:

public class SelectAll extends JFrame { private JTable table; private DefaultTableModel model; public SelectAll() { setTitle("查询全部成绩"); setLayout(new BorderLayout()); // 定义表头 String[] columns = {"学号", "姓名", "课程", "成绩", "录入时间"}; model = new DefaultTableModel(columns, 0) { @Override public boolean isCellEditable(int row, int column) { return false; // 表格不可编辑 } }; table = new JTable(model); JScrollPane scrollPane = new JScrollPane(table); add(scrollPane, BorderLayout.CENTER); loadData(); // 加载数据 pack(); setLocationRelativeTo(null); setVisible(true); } private void loadData() { List<Student> students = JDBCUtils.selectAll(); model.setRowCount(0); // 清空原有数据 for (Student s : students) { model.addRow(new Object[]{ s.getId(), s.getName(), s.getCourse(), s.getScore(), s.getCreateTime() }); } } }

这里的关键细节:
-model.setRowCount(0)必须在循环前执行,否则数据会重复叠加;
-isCellEditable(false)禁用编辑,避免学生误点单元格修改数据(课设不要求表格内编辑);
-JScrollPane包裹JTable,确保数据超屏时可滚动,这是Swing GUI的标配;
-pack()在add组件后调用,让窗口自适应内容大小,比固定setSize(800,600)更专业。

4. 实操过程与核心环节实现:从零开始导入运行的完整指南

4.1 环境准备:三步搞定本地运行环境

第一步:安装MySQL并创建数据库
下载MySQL Community Server 8.0(推荐8.0.33,机房兼容性最好),安装时记住root密码(默认是123456,与JDBCUtils.java中一致)。安装完成后,用命令行验证:

mysql -u root -p # 输入密码123456后进入MySQL命令行 SHOW DATABASES; # 应该看到stus_db(如果之前导入过)或空列表

若未创建数据库,手动执行:

CREATE DATABASE stus_db CHARACTER SET utf8mb4;

第二步:导入stus.sql建表脚本
打开MySQL命令行(或Navicat/HeidiSQL等工具),切换到stus_db库:

USE stus_db; SOURCE /path/to/stus.sql; -- 替换为你的stus.sql绝对路径

执行后运行SELECT COUNT(*) FROM students;,应返回3,证明测试数据已导入。

第三步:配置JDBC驱动jar包
下载mysql-connector-java-8.0.33.jar(注意必须是8.x版本,5.x不兼容MySQL 8.0)。在IDEA中:
- File → Project Structure → Libraries → + → Java → 选择jar包
- 在Eclipse中:右键项目 → Build Path → Configure Build Path → Libraries → Add External JARs

提示:如果运行时报错“java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver”,一定是jar包没加对,或者加到了错误的Module里。务必确认jar包出现在External Libraries目录下,而非src目录内。

4.2 IDE导入与运行:以IDEA为例的详细步骤

步骤1:新建空项目
File → New → Project → Empty Project → Next → 输入项目名(如StuScoreSystem)→ Finish。

步骤2:导入源码
将压缩包内所有.java文件(Add.java、Update.java等)和stus.sql拖入IDEA的src目录。注意:
- 不要拖整个src文件夹,而是拖文件到IDEA的src节点下;
- 图片资源(.png文件)放入src/img子目录,IDEA会自动识别为资源路径;
- .gitignore等配置文件可忽略,课设不需要Git管理。

步骤3:设置主类
右键MyMain.java → Run ‘MyMain.main()’,此时会报错“找不到符号JDBCUtils”,因为JDBC驱动未加载。按4.1第三步配置jar包后,再次运行即可。

步骤4:首次运行验证
启动后出现登录窗口,输入用户名admin,密码123456,点击登录。成功后弹出主菜单窗口,点击“查询全部”,应看到JTable显示3条测试数据。此时打开MySQL命令行执行SELECT * FROM students;,对比数据一致性——这是验证“Java ↔ MySQL双向通信正常”的黄金标准。

注意:如果登录后主菜单空白或按钮无响应,大概率是JDBC连接超时。检查JDBCUtils.java中URL的端口号(默认3306)是否与MySQL实际端口一致,可在MySQL命令行执行SHOW VARIABLES LIKE 'port';确认。

4.3 功能模块联动调试:以“添加成绩”为例的全流程追踪

我们以Add.java为例,演示如何从点击按钮到数据落库的完整链路:

前端触发:MyMain.java中addBtn的ActionListener:

addBtn.addActionListener(e -> { new Add().setVisible(true); // 弹出添加窗口 });

界面交互:Add.java创建JDialog弹窗,含4个输入框(学号可为空,由MySQL AUTO_INCREMENT生成)和“确定”按钮:

JButton confirmBtn = new JButton("确定"); confirmBtn.addActionListener(e -> { String name = nameField.getText().trim(); String course = courseField.getText().trim(); String scoreStr = scoreField.getText().trim(); if (name.isEmpty() || course.isEmpty() || scoreStr.isEmpty()) { JOptionPane.showMessageDialog(null, "请填写完整信息", "错误", JOptionPane.ERROR_MESSAGE); return; } try { double score = Double.parseDouble(scoreStr); if (score < 0 || score > 100) { JOptionPane.showMessageDialog(null, "成绩必须在0-100之间", "错误", JOptionPane.ERROR_MESSAGE); return; } // 调用数据库插入 String sql = "INSERT INTO students (name, course, score) VALUES (?, ?, ?)"; int rows = JDBCUtils.executeUpdate(sql, name, course, score); if (rows > 0) { JOptionPane.showMessageDialog(null, "添加成功!", "提示", JOptionPane.INFORMATION_MESSAGE); dispose(); // 关闭当前窗口 } } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(null, "成绩必须是数字", "错误", JOptionPane.ERROR_MESSAGE); } catch (SQLException ex) { JOptionPane.showMessageDialog(null, "数据库错误:" + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE); } });

后端执行:JDBCUtils.executeUpdate()执行预编译SQL,参数自动绑定,返回影响行数。

数据验证:回到MySQL命令行,SELECT * FROM students ORDER BY id DESC LIMIT 1;,应看到最新插入的记录,且id为4(前三条是1/2/3)。

这个流程覆盖了GUI事件监听、输入校验、异常处理、数据库操作、反馈提示六个教学要点,每一步都有明确的代码位置和调试方法,学生可以逐行打断点验证。

5. 常见问题与排查技巧实录:那些课设答辩时高频踩坑点

5.1 数据库连接失败的四大原因及速查表

现象可能原因排查命令/步骤解决方案
运行Login.java报“Communications link failure”MySQL服务未启动Windows:服务管理器中找MySQL80,启动;Mac:brew services start mysql启动MySQL服务
登录窗口点击无反应,控制台无输出JDBC驱动jar包未正确添加IDEA:Project Structure → Libraries,确认mysql-connector-java-8.0.33.jar存在重新添加jar包,确保在External Libraries下
报错“Unknown database ‘stus_db’”数据库未创建或名称拼错MySQL命令行:SHOW DATABASES;查看是否存在stus_db执行CREATE DATABASE stus_db CHARACTER SET utf8mb4;
插入数据后MySQL中查不到,但Java提示“添加成功”JDBC URL中useSSL=false缺失检查JDBCUtils.java第8行URL字符串在URL末尾添加?useSSL=false&serverTimezone=Asia/Shanghai

实操心得:我让学生养成习惯,每次遇到连接问题,先在MySQL命令行执行mysql -u root -p -h 127.0.0.1 -P 3306,能连上说明MySQL服务和网络正常,问题一定出在Java端配置。

5.2 Swing界面异常的典型场景与修复

场景1:窗口启动后一片空白,只有边框
原因:忘记调用setVisible(true),或pack()add()组件之前执行。
修复:检查MyMain.java构造方法末尾是否有setVisible(true),以及pack()是否在所有add()之后。

场景2:点击按钮无响应,控制台无报错
原因:ActionListener未正确绑定,或按钮被添加到错误的容器。
修复:在按钮创建后立即打印日志:

addBtn.addActionListener(e -> { System.out.println("添加按钮被点击"); // 添加这行 new Add().setVisible(true); });

如果控制台没输出,说明监听器没绑上,检查是否写了addBtn.addActionListener(...)而非button.addActionListener(...)(变量名写错)。

场景3:JTable显示中文为“???”
原因:MySQL数据库、表、连接URL三者字符集不一致。
修复:执行以下SQL统一字符集:

ALTER DATABASE stus_db CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; ALTER TABLE students CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

并在JDBC URL中确保有characterEncoding=utf8mb4参数。

5.3 课设答辩高频问题应答指南

Q1:为什么用JDBCUtils封装,而不把数据库操作直接写在Add.java里?
A:这是为了遵循“高内聚低耦合”原则。Add.java只关注“添加成绩”的业务逻辑(收集用户输入、校验数据),JDBCUtils只关注“如何与数据库交互”(建立连接、执行SQL、关闭资源)。这样修改数据库连接参数(如换密码)只需改JDBCUtils.java一处,不影响所有业务类。就像餐厅里厨师(业务类)只管做菜,采购员(工具类)负责买食材,分工明确效率高。

Q2:JDBCUtils里Connection为什么不做成单例?
A:Connection是线程不安全的,且MySQL连接有最大并发数限制。如果全局单例,多个用户同时操作会导致连接被抢占,出现“Connection closed”异常。而每次操作都新建Connection(用完即关),虽然稍慢,但保证了线程安全和资源可控,符合课设“功能正确优先于性能优化”的要求。

Q3:管理员权限为什么用静态变量,不存Session或Cookie?
A:因为这是桌面应用(Swing),不是Web应用。桌面程序没有HTTP Session概念,Cookie是浏览器机制。静态变量是Swing桌面程序中最简单有效的跨窗体状态传递方式,所有窗口都能访问Admin.currentUserRole,且生命周期与JVM一致,完全满足课设需求。

Q4:如果要扩展“按课程查询”,代码怎么改?
A:在SelectAll.java基础上新增SelectByCourse.java,界面加一个JComboBox课程选择框,查询逻辑改为:

String sql = "SELECT * FROM students WHERE course = ?"; List<Student> students = JDBCUtils.executeQuery(sql, selectedCourse);

然后在MyMain.java主菜单添加“按课程查询”按钮,指向新类。这种增量式扩展,正是面向对象“开闭原则”的体现——对扩展开放,对修改关闭。

6. 代码优化与教学延伸:从课设到工程能力的跃迁路径

6.1 当前代码的可改进点(供学有余力者挑战)

虽然这个项目完美满足课设要求,但若想向工程实践靠拢,有三个值得动手的优化方向:

第一,引入连接池替代每次新建Connection
当前JDBCUtils.getConnection()每次调用都新建物理连接,效率低。可引入HikariCP(轻量级,仅2个jar包),改造getConnection()方法:

private static HikariDataSource dataSource; static { HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/stus_db?useSSL=false"); config.setUsername("root"); config.setPassword("123456"); config.setMaximumPoolSize(5); dataSource = new HikariDataSource(config); } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); // 从此获取的是连接池中的连接 }

这样既保持了原有接口不变,又提升了并发性能,还能自然引出“连接池原理”“最大连接数设置依据”等进阶话题。

第二,用DAO模式重构数据访问层
将JDBCUtils中所有数据库操作方法移到StudentDao.java中:

public class StudentDao { public List<Student> findAll() { /* 调用JDBCUtils.executeQuery */ } public void insert(Student student) { /* 调用JDBCUtils.executeUpdate */ } public void update(Student student) { /* ... */ } }

业务类(Add.java等)只依赖StudentDao接口,不直接调用JDBCUtils。这种分层让代码更易测试(可mock StudentDao),也符合企业开发规范。

第三,增加输入校验的国际化支持
当前提示框全是中文,可引入ResourceBundle实现中英文切换:

ResourceBundle bundle = ResourceBundle.getBundle("messages", Locale.getDefault()); JOptionPane.showMessageDialog(null, bundle.getString("input_empty"), bundle.getString("error"), JOptionPane.ERROR_MESSAGE);

对应messages_zh_CN.properties文件写input_empty=请填写完整信息,messages_en_US.properties写input_empty=Please fill in all fields。这能让学生理解“国际化”不是玄学,而是资源文件+Locale的组合拳。

6.2 教学价值再挖掘:如何把这个项目变成你的技术简历亮点

很多学生交完课设就删掉代码,其实这个项目是绝佳的“能力证明载体”。我建议你做三件事:

第一,给代码写README.md
不是简单写“这是一个成绩系统”,而是用Markdown展示:
- 架构图(文字描述即可:Swing GUI ↔ JDBCUtils ↔ MySQL);
- 快速启动指南(复制粘贴就能跑的3条命令);
- 截图对比(登录页/主菜单/添加界面,标注关键组件);
- 已知问题(如“暂不支持批量导入”,体现诚实和反思)。

第二,在GitHub建公开仓库
把项目推到GitHub,设置开源许可证(MIT即可),在个人简历“项目经验”栏写:

Java Swing学生成绩管理系统| GitHub
- 独立开发基于Swing的桌面应用,实现学生信息CRUD及管理员权限控制
- 设计MySQL数据库(stus.sql),通过JDBCUtils封装连接与操作,保障SQL注入防护
- 采用MVC思想分层(GUI层/业务层/数据访问层),代码可读性获课程组评分98/100

第三,录制3分钟演示视频
用OBS录屏,旁白讲解:
- “这是登录界面,输入admin/123进入系统”(展示安全性);
- “点击添加,输入张三/Java/95.5,点击确定”(展示核心功能);
- “回到MySQL命令行,SELECT确认数据已持久化”(展示前后端贯通);
- “所有代码100%原创,无外部框架依赖”(强调教学合规性)。

这个视频可直接发给实习面试官,比千言万语的自我介绍更有说服力。

最后分享个小技巧:我在指导学生时,会让大家在MyMain.java的setTitle()里加入学号,比如setTitle("学生成绩管理系统 - 2023114521"),答辩时老师一眼看到学号,就知道这是你的原创作品,不是网上抄的。这种细节,往往就是加分项。

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

简介:一个开箱即用的Java学生成绩管理桌面程序,基于Swing构建图形界面,支持学生信息录入、成绩增删改查、管理员登录等基础教务功能。后端使用MySQL存储数据,压缩包内附stus.sql建表脚本,导入即可运行。所有功能模块独立封装:Add.java负责添加成绩,Update.java处理修改,SelectAll.java展示全部记录,Delete.java执行删除,Login.java和Admin.java实现权限控制,JDBCUtils.java统一管理数据库连接与CRUD操作。项目结构清晰,类文件命名规范,适配IDEA和Eclipse,直接导入后运行MyMain.java或Main.java即可启动主界面。配套提供9张真实运行截图,覆盖登录页、主菜单及各操作界面,直观呈现交互流程。代码无冗余依赖,不调用外部框架,符合高校Java课程设计对原创性、可读性与实现边界的教学要求。


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

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

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

立即咨询