ARTICLE DETAIL

资讯详情

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

Swing+MySQL医院挂号系统课设:核心代码与避坑指南

Swing+MySQL医院挂号系统课设:核心代码与避坑指南 简介这套医院挂号系统是一份基于 Java Swing 与 MySQL 的高校课程设计项目源码面向需要完成 Java 课设或快速上手图形界面数据库开发的同学解决从需求分析到编码实现中的常见难题。系统涵盖患者挂号、医生看诊、管理员维护、号源查询与增删改查等功能模块因来自真实接单项目结构清晰且可正常运行界面风格较为朴素更契合本科课设验收要求。压缩包共 75 个文件大小约 175KB包含 14 个 Java 源文件、38 个 class 编译文件、12 张 png 界面素材、7 个 xml 配置文件以及 1 份 MySQL 数据库脚本和登录账号密码导入工程并配置好数据库即可运行。目前该资源已有 267 人浏览学习是一份紧凑但完整的课设参考项目可直接提交或在此基础上扩展预约排班、统计分析等功能。1. 医院挂号系统课设资源Swing MySQL 能跑通的核心代码与数据库脚本说个 Java 课设的现实老师要的不是界面多精致而是“能运行、有登录、有增删改查、连得通数据库”。医院挂号系统恰好把这四件事全占了还多了一层多角色分发逻辑是课设题里最典型的综合练习。这份资源做成了 Swing 桌面端管理员、医生、用户三种角色分开登录挂号、退号、按编号查、全量查、用户维护都在源码 14 个 Java 文件平铺在 src 目录下另配一份 yygh.sql 数据库脚本导入即可用。它最打动我的点是“没过分美化”——界面保持在课设应有的朴素水平作为课程设计的真实参考反而更有说服力。适合正在赶课设、想要一套稳定运行代码做比对的 Java 学生也适合想搞明白 JDBC 怎么塞进 Swing 按钮事件里的初学者。下面从源码结构、运行复现、核心代码、常见坑四个角度拆开讲。2. 源码结构拆解14 个 Java 类如何撑起三端挂号业务压缩包解开后的 src 目录是平铺结构没有 package 层级。这对课设来说反而是好事IDEA 打开不会因为包路径对不上而大量报红。我按文件的实际职责把它们分成四组连接工具、登录入口、角色主窗体、业务操作类。理解这个分组后面排查问题时能第一时间判断该找哪个文件。2.1 按职责给 14 个 Java 文件分组定位先看一组最核心的JDBCUtils.java 是所有数据库操作的公共依赖负责加载 MySQL 驱动、建立连接、关闭资源其他类里的查询和增改都要先经它拿到 Connection。Login.java 是程序入口也是业务的第一道关卡只有通过了账号密码验证后续窗体才有意义。角色主窗体有 3 个AdminMain.java 对应管理员端DoctorMain.java 对应医生端UserMain.java 对应患者端。这三个窗体是登录成功后按角色类型去实例化的内部通常嵌入一个 JTable 表格组件用来展示当前角色能看到的业务数据。剩下的业务操作类按功能归类我用一张表把文件映射关系列出来分组文件职责连接工具JDBCUtils.java驱动加载、连接建立、资源关闭登录入口Login.java账号密码验证与角色跳转角色主窗体AdminMain.java / DoctorMain.java / UserMain.java管理员、医生、用户三个端的主界面挂号业务GHAdd.java / GHDelete.java新增挂号单、退号删除通用 CRUDAdd.java / Delete.java / Update.java / SelectAll.java / SelectByNum.java通用增删改查与按编号查询用户专属逻辑UserSelectAll.java / WenZ.java用户记录查询、问诊操作这份地图对照表帮我省了很多逐个双击文件的功夫。需要注意Add、Delete、Update 这些类名不带业务前缀看不出操作对象是用户表还是挂号记录表具体作用要看调用它的主窗体上下文。比如管理员端的 Add 大概率是新增用户账号而医生端操作的对象则集中在挂号状态和问诊记录上。真正读代码时先看窗体按钮绑定了哪个类再看那个类里 SQL 操作的表名职责马上就清楚了。WenZ.java 在文件列表里比较特殊从命名习惯推断是“问诊”的拼音缩写承担医生说诊结果录入或查看的功能。UserSelectAll.java 是用户端的查询类与 SelectAll.java 的区别在于它查询的范围通常被限制为当前登录用户自己的记录而不是全表。GHAdd.java 和 GHDelete.java 是挂号业务的增和删GH 对应“挂号”首字母一个负责新增挂号单一个负责退号删除。2.2 yygh.sql 的建表逻辑挂号单和用户信息的关系设计yygh.sql 是这份资源里最不能丢的文件。out 目录和 .idea 配置删了能重建脚本丢了就得重写。用 Navicat 或 IDEA 数据库面板打开脚本看到的表结构通常是用户表和挂号记录表两类。用户表一般命名为 usr 或 user字段至少包含 id、username、password、type——type 用来区分管理员、医生、患者三个角色。挂号记录表的字段围绕挂号业务展开大致是挂号编号、患者姓名、科室、医生、挂号时间、状态这几项。表之间的关联方式课设项目常见做法是直接冗余患者姓名字段省去联表查询。虽然不符合第三范式但对于单机课设来说界面展示时少一次 JOIN 就意味着少一层出错可能。我在同类项目里也一直沿用这个思路——课设代码的首要目标是稳定、易懂不是设计模式考试。打开脚本后你会看到类似这样的建表骨架CREATE TABLE IF NOT EXISTS usr ( id INT NOT NULL AUTO_INCREMENT, username VARCHAR(50) DEFAULT NULL, password VARCHAR(50) DEFAULT NULL, type INT DEFAULT NULL COMMENT 1-管理员 2-医生 3-用户, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8; CREATE TABLE IF NOT EXISTS gh ( gh_id INT NOT NULL AUTO_INCREMENT, patient_name VARCHAR(50) DEFAULT NULL, dept VARCHAR(50) DEFAULT NULL, doctor VARCHAR(50) DEFAULT NULL, gh_time DATETIME DEFAULT NULL, gh_status VARCHAR(20) DEFAULT 待就诊, PRIMARY KEY (gh_id) ) ENGINEInnoDB DEFAULT CHARSETutf8;上面这段是此类课程设计最标准的表结构骨架真实脚本里字段名和注释可能有出入以文件里的实际建表语句为准。看表结构时重点盯两处一是 type 字段的注释这决定了角色的常量约定二是 gh_status 的默认值后续所有状态流转都围绕着它做判断。脚本末尾通常还有几条 INSERT 语句用于预置管理员、医生和测试患者的账号这是运行后第一次登录的凭证来源。导入脚本的时候有个顺序问题要注意很多图形化工具选中某个库再执行外部 SQL 文件时会自动跳过 CREATE DATABASE 语句结果就是后续建表报 Unknown database。最稳的做法是手动先建库再导表。表名和字段名的反引号不要删MySQL 8.0 环境下部分字段名如 order、status 不带反引号会直接冲突报错。2.3 登录后的跳转链路账号类型决定打开哪个主窗体登录流程是整条业务链路的咽喉。Login.java 拿到界面输入的账号密码后通过 JDBCUtils 建立连接在用户表里比对记录查到后取出 type 字段再用判断语句分发type 为 1 就打开 AdminMain为 2 打开 DoctorMain为 3 打开 UserMain。这里“传用户信息”有两种常见实现构造方法传参或者把当前用户信息存成静态变量。构造方法传参更符合面向对象习惯但课设里大量使用静态变量存当前登录对象因为所有子窗体都能直接访问不用层层传递。两种方案在这个体量的项目里都完全够用区别在于答辩时怎么说。构造方法传参可以讲“职责清晰、状态不再全局可见”静态变量则可以讲“符合单例思想、减少了参数传递复杂度”。我建议选一种自己真正理解的老师追问时能自圆其说就行。这个链路里藏着一个隐蔽的坑部分课设会把角色判断直接拼进 SQL 的 WHERE 子句同时比对 username、password、type 三个条件。问题在于账号错误、密码错误、角色不存在时返回的都是同一个“查询结果为空”用户根本不知道具体错在哪。如果你后续调试遇到“谁登录都提示账号或密码错误”优先怀疑这里是不是把角色条件也拼进去了拆开单独查账号密码问题立刻暴露。3. 本地复现JDK MySQL 从零跑通整套课设这一章是动手环节目标是让项目在你电脑上运行起来看到登录窗口、以三种角色登录、验证数据能增能删能查。如果 JDK、IDEA、MySQL 已经装好可以跳过 3.1 直接从 3.2 开始。整个过程大概二十分钟其中一大半时间花在数据库导入和依赖配置上。3.1 环境版本选型为什么 JDK 8 MySQL 5.7 最不容易出问题这套代码用的是纯 JDBC Swing没有引入 Maven 或 Gradle环境要求很低。JDK 1.8 是首选Swing 在 JDK 8 里是内置组件不需要额外配置JDK 11 以上虽然也能编译但高版本 JDK 对 Swing 的默认外观和字体渲染有细微变化界面效果可能会和资源里的截图不一致答辩时容易被老师追问。MySQL 选 5.7 或 8.0 都行但驱动连接参数有差异MySQL 5.7 用 mysql-connector-java 5.x 版本8.0 则需要更细的连接串配置。有一个常见的认知误区代码里写 Class.forName(com.mysql.jdbc.Driver)在 MySQL 8.0 下依然能加载因为驱动做了兼容映射。真正会翻车的是连接 URL 缺少 serverTimezone 参数时8.0 驱动会抛 The server time zone value 异常。解决办法是在 URL 末尾加 serverTimezoneAsia/Shanghai。至于驱动 jar 包它不在项目源码里需要单独下载5.1.49 版本适配 JDK 8 和 MySQL 5.7兼容性最好。MySQL 安装也多说一句Windows 上直接去官网下载 mysql-installer安装时选 Server only端口默认 3306密码设成好记的。装完打开服务管理器确认 MySQL 服务处于“正在运行”状态。我处理过很多“代码连不上数据库”的报错排查到最后发现服务根本没启动这类基础问题最费时间。3.2 导数据命令行导入 yygh.sql 的正确姿势拿到 SQL 脚本后第一件事不是打开源码而是把数据库建好。推荐用命令行导入步骤最干净。打开终端先登录 MySQLmysql -u root -p123456这里的 -p 后面直接跟你的密码如果密码含特殊字符改成交互式输入比较稳妥。登录后依次执行CREATE DATABASE IF NOT EXISTS yygh DEFAULT CHARSET utf8mb4; USE yygh; SOURCE D:/workspace/yygh.sql;SOURCE 后面写 yygh.sql 的实际路径Windows 下正反斜杠都行路径含空格时要用引号包起来。执行完以后用 SHOW TABLES; 确认表是否生成。如果表存在了顺手查询一条数据SELECT * FROM usr;能看到预置的用户记录说明数据已就位。用 Navicat 或 DataGrip 导入也行但要注意图形工具默认在当前选中的数据库上执行 SQL脚本里如果没有 CREATE DATABASE 语句你必须手动先建一个 yygh 库再运行脚本。相比起来命令行一次性执行原生脚本最不容易出错。导入时遇到 Incorrect datetime value 报错是 MySQL 的 sql_mode 不允许零日期值。两个解决办法一是把脚本中的日期改成 2023-01-01 08:00:00 这类标准格式二是在 MySQL 配置文件的 [mysqld] 段去掉 NO_ZERO_DATE 模式后重启服务。课设场景我建议直接改脚本日期值改配置影响全局容易引发其他不必要的故障。3.3 改配置JDBCUtils 连接参数必须对齐本机环境数据库导好了代码里的连接信息还是作者本机的。打开 JDBCUtils.java需要重点关注的就是 URL、USER、PASSWORD 三个常量private static final String URL jdbc:mysql://localhost:3306/yygh?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8; private static final String USER root; private static final String PASSWORD 123456;URL 里的 localhost:3306 是默认的本地地址和端口如果你的 MySQL 改了端口这里要同步修改。USER 和 PASSWORD 改成你自己安装 MySQL 时设置的账号密码。这三个值任一个不对运行任何功能都会在第一次数据库操作时报 Access denied 或 Communications link failure。注意 URL 后半段参数useSSLfalse 关掉了安全连接校验本地开发可以不要证书characterEncodingutf8 保证中文写入不乱码serverTimezoneAsia/Shanghai 是给 MySQL 8.0 驱动用的时区声明。没有这三个参数常见的问题就是中文乱码和时区报错。改完这三个参数后还要确认驱动 jar 是否已被 IDEA 识别右键 jar 包选择 Add as Library弹出对话框确认模块是当前项目这样 IDEA 构建时才会把 jar 带上。3.4 运行与验证从 Login 主类启动并检查三种角色IDEA 里打开项目根目录等索引完成。在 src 目录下找到 Login.java右键选择 Run Login.main()。正常情况下会弹出 Swing 登录窗口。窗口没弹出来时看 Run 面板的红色堆栈报 ClassNotFoundException 是缺驱动报 SQLException 是连接参数不对报 Access denied 是账号密码不匹配。这三种报错都有明确的修复路径按 3.1 到 3.3 的步骤排查即可。登录用的账号密码在 SQL 脚本的 INSERT 语句里打开脚本搜索 INSERT INTOusr能看到管理员、医生、测试患者的明文记录。课设项目里密码基本是明文存储这个没有安全性问题因为数据是自己录的测试数据。首次登录建议先用管理员账号管理员界面能看到全部挂号记录配合表格里是否有数据来验证整条链路。登录进去后如果表格有数据说明从 Java 到 MySQL 的全部通路已经打通。能走到这一步项目基本已经跑起来了。剩下的工作就是换上自己院系的信息、改成自己系统的名字准备答辩素材了。4. 核心业务代码走读登录验证、挂号增删与查询的实际写法这一章沿着“登录 → 主窗体 → 业务操作”的执行流挑四个最有代表性的文件拆开讲。课设代码没有抽象层、没有工厂模式所有逻辑都直接压在类和方法里作为初学者顺着执行流走一遍是最快的学习方式。下面的代码片段是这类课设最典型的写法真实源码的变量命名和顺序可能有差异但核心流程高度一致。4.1 JDBCUtils驱动加载、连接建立与资源关闭的三板斧JDBCUtils 是这份代码里唯一的基础设施类其他所有类的数据库操作都依赖于它。核心逻辑可以概括为三件事静态代码块加载驱动、getConnection 返回连接、close 关闭资源。代码骨架如下public class JDBCUtils { private static final String DRIVER com.mysql.jdbc.Driver; private static final String URL jdbc:mysql://localhost:3306/yygh?useSSLfalsecharacterEncodingutf8; private static final String USER root; private static final String PASSWORD 123456; static { try { Class.forName(DRIVER); } 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) { try { if (rs ! null) rs.close(); if (stmt ! null) stmt.close(); if (conn ! null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }这段是 JDBC 的经典三段式。Class.forName(DRIVER) 把驱动类加载进 JVMDriverManager 在 getConnection 时自动匹配已注册的驱动。close 方法值得注意的是关闭顺序先关 ResultSet再关 Statement最后关 Connection。数据库资源从里到外依次释放顺序搞反会导致连接未完全释放长期运行可能出现连接耗尽。这个类里没有连接池每个操作都是即用即连、用完即关。课设项目的并发量几乎为零这种写法完全够用而且比连接池更容易让答辩老师理解。调用方只需要在 finally 块里调用 close不需要关心驱动的生命周期。有一个细节可以注意e.printStackTrace() 在课设代码里是标配虽然生产环境不推荐但课设阶段它就是最高效的排查方式看到控制台堆栈比看日志文件直观得多。4.2 Login.java登录验证的 SQL 拼接与角色分发Login.java 的登录按钮事件处理是整条业务链的起点。逻辑分为两步查用户表得到账号密码匹配结果然后根据 type 值分发到不同主窗体。典型写法如下String sql SELECT * FROM usr WHERE username username AND password password ; stmt conn.createStatement(); ResultSet rs stmt.executeQuery(sql); if (rs.next()) { int type rs.getInt(type); if (type 1) { new AdminMain().setVisible(true); } else if (type 2) { new DoctorMain().setVisible(true); } else if (type 3) { new UserMain().setVisible(true); } loginFrame.dispose(); } else { JOptionPane.showMessageDialog(null, 账号或密码错误); }字符串拼接 SQL 是课设代码的常态但它的隐患很明显用户输入的内容可以改变 SQL 语义。例如用户名输入 1 OR 11拼接后 WHERE 条件恒成立不用密码也能登录。这在单机课设里没有实际攻击风险但用 PreparedStatement 替代只需要多写两行代码String sql SELECT * FROM usr WHERE username ? AND password ?; PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, username); ps.setString(2, password); ResultSet rs ps.executeQuery();同样的业务效果但带参方式避免用户输入破坏 SQL 结构。建议你拿到源码后顺手把拼接改成 PreparedStatement成本极低答辩时还能作为一条加分项“我考虑了 SQL 注入问题所以用了预编译语句”。这个细节在课设答辩里非常加分。角色分发的逻辑同样值得品读type 123 对应三个不同主窗体这是一种硬编码的策略分发。想让代码更有弹性可以用 switch 或工厂方法但课设阶段 if-else 足够。真正要注意的是 new AdminMain().setVisible(true) 之后登录窗体要 dispose 掉否则会出现两个窗口叠加的视觉混乱。4.3 GHAdd 与 GHDelete挂号、退号两条增删链路挂号在业务上就是“往挂号表里插入一条新记录”。GHAdd.java 的事件处理逻辑从窗体文本框取出科室、医生、患者姓名、联系电话执行 INSERT 语句然后用受影响行数判断是否成功String sql INSERT INTO gh (patient_name, dept, doctor, gh_time, gh_status) VALUES (?, ?, ?, NOW(), 待就诊); PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, patientName); ps.setString(2, dept); ps.setString(3, doctor); int rows ps.executeUpdate(); if (rows 0) { JOptionPane.showMessageDialog(null, 挂号成功); } else { JOptionPane.showMessageDialog(null, 挂号失败请重试); }这段代码里 gh_time 用了 MySQL 的 NOW() 函数数据库服务端生成当前时间省去了 Java 端格式化日期的代码。gh_status 字段直接插入字符串“待就诊”是挂号业务的初始状态。后续医生在 DoctorMain 里执行 UPDATE 把它改成“已就诊”构成系统最简单的状态流转。GHDelete 对应退号操作核心是一条 DELETE 语句常见实现是根据挂号编号删除String sql DELETE FROM gh WHERE gh_id ?; PreparedStatement ps conn.prepareStatement(sql); ps.setInt(1, ghId); int rows ps.executeUpdate(); if (rows 0) { JOptionPane.showMessageDialog(null, 退号成功); refreshTable(); }executeUpdate 返回的是受影响的行数增删改操作成功与否就以它为准。refreshTable 是手动调用的表格刷新方法退号后界面要同步更新否则表格里还是旧数据。GHDelete 这类代码有个常见缺陷没有二次确认弹窗按钮一点数据就没了。建议补一段 JOptionPane.showConfirmDialog 做确认这个很容易实现但在答辩中能展现你考虑过数据误删风险。4.4 SelectByNum 与 SelectAll查询结果如何灌进 Swing 表格SelectAll 执行的是全表查询管理员登录后主窗体表格展示全部挂号记录。Java 端读取结果集并填充到表格的写法如下String sql SELECT * FROM gh; stmt conn.createStatement(); ResultSet rs stmt.executeQuery(sql); while (rs.next()) { Object[] row { rs.getInt(gh_id), rs.getString(patient_name), rs.getString(dept), rs.getString(doctor), rs.getString(gh_status) }; DefaultTableModel model (DefaultTableModel) table.getModel(); model.addRow(row); }这段代码把 ResultSet 的每一行转换为 Object 数组追加到 DefaultTableModel 中Swing 的 JTable 会感知模型变化并自动重绘。这里有一个类型对应关系数据库 INT 列对应 rs.getIntVARCHAR 列对应 getString类型不匹配会在运行时抛异常。常见的错误是把 INT 字段用 getString 取虽然 MySQL 驱动会自动转换但不一致的类型映射在复杂报表场景下会有隐患。SelectByNum 在查询条件上多了 WHERE 限定SELECT * FROM gh WHERE gh_id ?如果需求改成按患者姓名模糊查询就换成 LIKE 写法SELECT * FROM gh WHERE patient_name LIKE CONCAT(%, ?, %)注意这里用 CONCAT 拼接通配符而不是直接写 %?%后者会把问号当成字面量匹配。UserSelectAll 和 SelectAll 的区别同样体现在 WHERE 条件上UserSelectAll 多了一个用户范围限制把结果限定在当前登录用户自己的记录。这就是课设项目里最原始的数据隔离方式——不引入权限框架就在 SQL 条件上做文章。5. 避坑指南课设跑起来之前必查的五个点位拿到别人源码跑不通多数情况不是代码坏了是环境和数据没对齐。下面五条是我处理 Swing MySQL 课设时最常碰到的坑按出现概率排序。每条都是实际踩过的记录照着排除能省下大量排查时间。5.1 ClassNotFoundExceptionmysql 驱动 jar 没有进入项目依赖现象一运行 Login 就报 java.lang.ClassNotFoundException: com.mysql.jdbc.DriverRun 面板红色堆栈直接指向 JDBCUtils 的静态代码块。原因项目是纯源码形式交付MySQL 驱动 jar 没有被打进项目依赖。IDEA 打开项目时只会识别 src 目录下的 Java 源文件lib 目录如果存在但未右键添加编译能过运行时类加载失败。解决下载 mysql-connector-java 的 jar 包版本建议 5.1.49放到项目根目录的 lib 文件夹。右键 jar 选择 Add as Library弹出对话框确认作用范围是 Module 级别重新运行即可。验证是否真的加载成功展开 IDEA 右侧的 External Libraries能看到 mysql-connector 条目才算完事。5.2 Access deniedJDBCUtils 账号密码与本机 MySQL 不一致现象运行后第一次点登录按钮控制台报 java.sql.SQLException: Access denied for user rootlocalhost (using password: YES)。原因JDBCUtils 里写死的账号密码是作者本机环境的你本机 MySQL 设置的密码不同。源码作者的环境密码大概率是 123456而你自己装的 MySQL 可能设了更复杂的密码。解决先在 MySQL 客户端确认自己能正常登录然后在 JDBCUtils 里把 USER 和 PASSWORD 改成你自己的。改完顺手检查两处一是密码前后有没有意外空格二是输入的密码是不是在中文输入法状态下打的。有一次我排查了半小时最后发现冒号后面多了个不可见空格。5.3 中文乱码连接参数和表字符集要一起查现象登录后表格里的中文全是 ?? 或者方块英文和数字正常。原因字符集问题有两层一层是连接字符串里没有指定 characterEncodingutf8另一层是建表时默认字符集不是 utf8。只改其中一处乱码问题依然存在这是最容易迷惑人的地方。解决第一步在 JDBCUtils 的 URL 末尾加上 characterEncodingutf8第二步执行 SHOW CREATE TABLE gh; 看 CHARSET 是否为 utf8 或 utf8mb4如果是 latin1执行 ALTER TABLE gh CONVERT TO CHARACTER SET utf8mb4; 两个地方都改完重新运行乱码会彻底消失。注意 utf8mb4 是 utf8 的超集支持存储 emoji 表情建新表时优先选它。5.4 Unknown columnJava 代码字段名和建表语句对不上现象运行某个具体查询功能时报 java.sql.SQLSyntaxErrorException: Unknown column xxx in where clause。原因代码里 getString(字段名) 或 SQL 里的列名与建表语句不一致。这种不一致常见于字段改名后 Java 代码没同步更新或者复制别人代码时只改了 SQL 没改 Java 层的字段映射。解决打开 SQL 脚本找到建表语句把表结构的字段清单列出来和 Java 代码里的字段引用逐一比对。我一般用文本编辑器的查找替换功能先把所有表字段名找出来列在纸上然后再逐个对照 Java 文件。这个过程枯燥但有效这类错误属于低级 bug解决后基本不会再犯。5.5 窗口显示不全Windows 缩放下 Swing 不自动适配现象Swing 窗口弹出来了但界面只显示一半底部的按钮被截断鼠标点不到。原因Windows 系统的显示缩放比例不是 100%比如 125% 或 150%。Swing 基于 AWT 的布局在高 DPI 环境下不会自动缩放坐标是按 100% 缩放计算的导致界面被裁剪。解决最简单的方式是在运行配置的 VM options 里加上 -Dsun.java2d.dpiawarefalse。也可以在 main 方法第一行写入 System.setProperty(sun.java2d.dpiaware, false); 强制关闭高 DPI 感知界面会稍微模糊但保证完整显示。答辩演示时优先用缩放 100% 的电脑能彻底避开这个问题。6. 更稳的验证手法改一个挂号状态字段观察整条数据流第一轮跑通只说明环境没问题不代表业务逻辑正确。我拿到任何课设源码都会再做一次数据链路的穿透验证正向从数据库改数据看界面刷新反向从界面操作看数据库落库。两个方向各花两分钟能把界面层、逻辑层、数据层之间的断点全部暴露出来。6.1 正向验证改库表数据看前端刷新表现先从 MySQL 客户端执行一条 UPDATE把某条挂号记录的状态从“待就诊”改成“已就诊”UPDATE gh SET gh_status 已就诊 WHERE gh_id 1;回到 Swing 界面在管理员主窗体的表格区域触发一次刷新。如果改动正确反映到表格里说明从数据库读取、ResultSet 解析、DefaultTableModel 填充到表格重绘这条链路是通的。如果没有任何变化优先检查刷新按钮是否绑定了查询方法——很多课设界面上有一个“查询”按钮但事件监听代码可能是空的或者调用了错误的方法名。6.2 反向验证从界面操作查数据库落库结果反向验证同样直接在界面上新增一条挂号记录填写患者姓名、科室、医生点保存。然后去 MySQL 客户端执行SELECT * FROM gh ORDER BY gh_id DESC LIMIT 1;如果查到刚才那条记录说明 INSERT 链路完整。如果界面上弹了“挂号成功”但数据库里查不到问题大概率出在事务提交上。课设代码里通常不会显式写事务但如果有 setAutoCommit(false) 而没有 commit()数据就会被回滚。还有一个隐蔽场景刷新或新增操作里调用了错误的 DAO 方法比如按钮绑定的是 SelectAll 而不是 GHAdd这种情况界面表现和数据库状态完全对不上最迷惑人。两个方向的验证加一起不到五分钟却能把三层架构的每一段连接都检验一遍。从那以后我每次拿到课设源码第一遍跑通后都强制走一遍“改字段→看界面→改界面→查数据库”的闭环数据双向通路确认没问题再去谈业务优化和功能扩展。这个习惯让我少踩了很多演示现场翻车的坑希望也能帮到你。本文还有配套的精品资源点击获取
返回列表