Java Swing人事管理系统:JDBC+MySQL课程设计实战与避坑指南
简介这份资源是一套基于 Java Swing、JDBC 与 MySQL 实现的人事管理系统课程设计项目面向正在完成数据库课程设计、需要可运行参考案例的计算机相关专业学生。项目包含可视化软件界面覆盖人员信息维护、数据库连接与增删改查等典型业务场景适合作为课程设计模板或 JDBC 入门练手素材。压缩包共 24 个文件以 11 个 Java 源码文件、12 张 png 界面截图和 1 个 sql 数据库脚本为主整体约 143KB源码、界面效果与建库脚本相互对应便于快速理解项目结构与数据表设计。目前已有 3878 人学习下载。读者可从中获得完整的课程设计实现思路、Swing 界面与 JDBC 数据访问的配合方式以及可直接导入的数据库脚本作者也提示运行中出现的多为数据库版本差异导致的基础报错可自行排查解决适合借此积累排错经验。1. 从一份能跑起来的 Java Swing 人事管理系统说起很多同学做数据库课程设计时最头疼的不是 SQL 语句本身而是怎么把 JDBC、MySQL 和桌面界面串成一个能演示、能答辩、能交差的完整系统。这份mysqljava人事管理.zip就是冲着这个场景来的Java Swing 做界面JDBC 连 MySQL源码、图片资源、SQL 建库脚本都打包好了解压后src、images、databaseproject.sql各就各位。它解决的是“从零搭一个带图形界面的人事管理系统”这件事适合正在做课程设计、想拿一份可运行骨架改造成自己作业的在校生也适合想复习 JDBC 增删改查和 Swing 事件绑定的初级开发者。需要提前说清楚这份资源报的错基本都是数据库版本差异引起的基础错误不是代码逻辑崩了自己动手改改就能跑。2. 环境搭建与数据库初始化把 databaseproject.sql 灌进 MySQL2.1 为什么先锁版本JDBC 驱动和 MySQL 8 的时区坑这套代码用的是原生 JDBC没有 MyBatis、没有连接池所以驱动版本和数据库版本的匹配就是第一道门槛。MySQL 5.7 和 8.0 在连接串上差别不小最常见的翻车就是com.mysql.jdbc.Driver和com.mysql.cj.jdbc.Driver混用以及 8.0 必须显式指定时区。我一般会先确认本机 MySQL 版本再决定驱动包用mysql-connector-java-5.1.x还是mysql-connector-java-8.0.x。如果你装的是 MySQL 8.0连接 URL 里不加serverTimezone启动就会抛The server time zone value ???ú±ê×??± is unrecognized这个报错看着吓人其实就是时区没配对。常见做法是打开项目里的数据库配置文件通常是src下的.properties或直接写在 Java 工具类里把驱动类名、URL、用户名、密码四项对齐本机环境。下面这段是我按 MySQL 8.0 改好的连接配置可以直接抄// DBUtil.java 数据库连接工具类核心片段 public class DBUtil { // MySQL 8.0 用 cj 驱动5.7 用 com.mysql.jdbc.Driver private static final String DRIVER com.mysql.cj.jdbc.Driver; // 关键参数useSSL 关闭、serverTimezone 指定东八区、字符集 utf8 private static final String URL jdbc:mysql://localhost:3306/personnel? useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8; private static final String USER root; private static final String PASSWORD 你的密码; public static Connection getConnection() throws Exception { Class.forName(DRIVER); // 加载驱动 return DriverManager.getConnection(URL, USER, PASSWORD); } }逻辑说明Class.forName负责把驱动类注册进 DriverManager少了这行在部分容器里会报No suitable driver found。参数说明useSSLfalse避免本地连接时的 SSL 警告serverTimezoneAsia/Shanghai是 8.0 的硬性要求characterEncodingutf8保证中文姓名不乱码。改完这四项连接层基本就通了。2.2 导入 SQL 脚本并核对表结构databaseproject.sql是整套系统的数据底座里面一般包含建库、建表和初始数据。导入方式有两种命令行和图形工具都行。命令行更稳不容易因为编码问题把中文搞乱# 先建库再导入注意指定字符集 mysql -u root -p -e CREATE DATABASE personnel DEFAULT CHARACTER SET utf8mb4; # 导入脚本-p 后回车输入密码 mysql -u root -p personnel databaseproject.sql # 验证表是否建好 mysql -u root -p -e USE personnel; SHOW TABLES;逻辑说明第一条命令单独建库并锁定utf8mb4避免脚本里没写字符集导致中文变问号第二条把脚本灌进personnel库第三条列出所有表做核对。参数说明库名personnel要和 JDBC URL 里保持一致不一致就报Unknown database。导入后重点看员工表、部门表、工资表这几张核心表字段是否齐全字段类型和 Java 实体类要对得上比如id是int还是varchar对不上会在查询映射时抛类型转换异常。2.3 在 IDE 里跑通第一个查询环境配好后别急着点主界面先写个最小查询验证链路。这一步能帮你把“数据库问题”和“界面问题”分开省得后面排查时两头抓瞎public static void main(String[] args) { try (Connection conn DBUtil.getConnection(); Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery(SELECT COUNT(*) FROM employee)) { if (rs.next()) { System.out.println(员工总数 rs.getInt(1)); } } catch (Exception e) { e.printStackTrace(); // 报错先看这里别急着改界面 } }逻辑说明用 try-with-resources 自动关闭连接、语句和结果集避免连接泄漏。参数说明SELECT COUNT(*)只取一个数字不涉及字段映射能把驱动、URL、库名、表名四件事一次性验证完。这一步过了再启动 Swing 主界面出问题就基本能定位到界面层而不是数据层。3. Swing 界面与 JDBC 增删改查的对接事件、表格模型与事务3.1 从按钮点击到 SQL 执行一次完整的调用链Swing 的按钮事件和 JDBC 之间隔着一层很多新手卡在“点了按钮没反应”或者“数据没刷新”。完整链路是这样的用户点“新增”按钮 →ActionListener触发 → 读取文本框内容 → 拼装 SQL 或 PreparedStatement → 执行 → 重新查询并刷新JTable。这条链任何一环断了界面都不会更新。我一般把数据操作单独抽成一个 DAO 类界面只负责收集参数和调用这样排查时能明确是界面没触发还是 SQL 没执行。// 新增员工按钮的事件绑定 addBtn.addActionListener(e - { String name nameField.getText().trim(); String dept deptField.getText().trim(); if (name.isEmpty()) { // 前置校验别把空值塞进库 JOptionPane.showMessageDialog(null, 姓名不能为空); return; } try { EmployeeDao.add(new Employee(name, dept)); // 调 DAO 落库 refreshTable(); // 重新查一遍刷新表格 } catch (SQLException ex) { JOptionPane.showMessageDialog(null, 新增失败 ex.getMessage()); } });逻辑说明先做非空校验再落库避免脏数据落库成功后立刻刷新表格保证界面和数据库一致。参数说明trim()去掉首尾空格防止用户误输空格导致查询匹配不上refreshTable()内部重新执行SELECT并重建DefaultTableModel这是 Swing 表格刷新的标准做法。3.2 用 PreparedStatement 替代字符串拼接课程设计里最常见的写法是INSERT INTO employee VALUES( name )这种拼接有两个致命问题一是姓名里带单引号直接 SQL 报错二是给 SQL 注入留了口子。虽然课程设计不强调安全但养成用PreparedStatement的习惯答辩时也是加分项。下面是对比写法// 不推荐字符串拼接遇到 OBrien 这种名字直接崩 String badSql INSERT INTO employee(name, dept) VALUES( name , dept ); // 推荐PreparedStatement 占位符参数单独绑定 String sql INSERT INTO employee(name, dept) VALUES(?, ?); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, name); // 第一个 ? 绑姓名 ps.setString(2, dept); // 第二个 ? 绑部门 ps.executeUpdate(); }逻辑说明占位符?由驱动负责转义单引号、特殊字符都能安全处理。参数说明setString的下标从 1 开始不是 0这是新手最容易数错的地方executeUpdate用于增删改返回受影响行数executeQuery用于查询返回ResultSet两者别用混。3.3 表格数据绑定与刷新机制Swing 的JTable本身不存数据数据在TableModel里。很多人查完数据库直接new JTable(data, columns)结果一刷新就重建整个表格选中状态和滚动位置全丢。正确做法是持有DefaultTableModel引用刷新时先setRowCount(0)清空再逐行addRow// 初始化时持有 model 引用 DefaultTableModel model new DefaultTableModel( new String[]{工号, 姓名, 部门, 工资}, 0); JTable table new JTable(model); // 刷新方法清空后重新填充保留表格对象本身 private void refreshTable() { model.setRowCount(0); // 清空旧数据 String sql SELECT id, name, dept, salary FROM employee; try (Connection conn DBUtil.getConnection(); Statement stmt conn.createStatement(); ResultSet rs stmt.executeQuery(sql)) { while (rs.next()) { model.addRow(new Object[]{ rs.getInt(id), rs.getString(name), rs.getString(dept), rs.getDouble(salary)}); } } catch (SQLException e) { e.printStackTrace(); } }逻辑说明setRowCount(0)只清数据不换模型表格的列宽、排序、选中逻辑都保留。参数说明addRow里字段顺序必须和表头一一对应错位会导致工资列显示姓名这种低级错误rs.getDouble(salary)对应数据库里的decimal或double类型类型不匹配会抛异常。4. 避坑与排查数据库版本差异引发的五类典型报错4.1 驱动类找不到ClassNotFoundException现象启动直接抛java.lang.ClassNotFoundException: com.mysql.jdbc.Driver。原因项目用的是 5.x 驱动类名但实际引入的是 8.0 的 jar 包或者 jar 根本没加进构建路径。解决确认lib目录下的 connector 版本8.0 改成com.mysql.cj.jdbc.Driver并在 IDE 的 Project Structure 里把 jar 加到 Libraries。这一步不做后面所有数据库操作都免谈。4.2 时区报错serverTimezone 未指定现象连接时抛The server time zone value ... is unrecognized。原因MySQL 8.0 默认时区和 JDBC 驱动解析不一致。解决在 URL 后追加serverTimezoneAsia/Shanghai或者用GMT%2B8。这是 8.0 环境最高频的一个坑改一个参数就解决别去动系统时区。4.3 中文乱码库、表、连接三层字符集不统一现象界面显示中文正常存进数据库变成问号或者查出来是乱码。原因建库时没指定utf8mb4或者 JDBC URL 里漏了characterEncodingutf8。解决三层都要对齐——建库用utf8mb4连接串加characterEncodingutf8Swing 读取时确认文件编码是 UTF-8。三层缺一层都可能乱码。4.4 主键冲突自增字段被手动赋值现象新增时报Duplicate entry 1 for key PRIMARY。原因SQL 脚本里id是自增但插入语句手动写了id值或者多次导入脚本导致数据重复。解决插入时不要带id字段让数据库自增如果脚本重复导入过先TRUNCATE TABLE清空再重新导入。4.5 连接未关闭程序跑久了报 Too many connections现象反复操作后报Too many connections。原因每次查询都new连接但没关连接数被耗尽。解决统一用 try-with-resources 包裹Connection、Statement、ResultSet或者把连接管理收进DBUtil里做单例。课程设计数据量小但养成关闭习惯很重要。5. 二次开发与验证把课程设计改成自己的东西5.1 加一个按部门筛选的查询功能原系统如果只有全量查询答辩时容易被问“能不能筛选”。加一个下拉框按部门过滤改动量很小但演示效果好。核心是把SELECT加上WHERE条件并用PreparedStatement绑定// 部门下拉框触发筛选 deptBox.addActionListener(e - { String selected (String) deptBox.getSelectedItem(); model.setRowCount(0); String sql SELECT id, name, dept, salary FROM employee WHERE dept ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, selected); ResultSet rs ps.executeQuery(); while (rs.next()) { model.addRow(new Object[]{rs.getInt(id), rs.getString(name), rs.getString(dept), rs.getDouble(salary)}); } } catch (SQLException ex) { ex.printStackTrace(); } });逻辑说明下拉框选中值作为参数绑定避免拼接。参数说明deptBox的选项要和数据库里dept字段的实际值一致否则查出来是空表如果要做“全部”选项加一个分支判断选中“全部”时走不带WHERE的查询。5.2 验证清单交付前必须走一遍的检查项改完代码别急着打包按下面这张表逐项过一遍能挡掉大部分答辩现场的尴尬检查项验证方式通过标准数据库连接运行最小查询 main能打印员工总数新增功能界面录入一条记录表格刷新后出现新行删除功能选中一行点删除表格和数据库同步减少修改功能改工资后保存重新查询数值已变中文显示录入中文姓名界面和数据库都不乱码空值校验不填姓名直接提交弹提示而非报错这张表看着简单但每年课程设计翻车最多的就是“新增成功但表格没刷新”和“中文姓名存进去变问号”这两条。前者是忘了调refreshTable()后者是字符集没对齐。5.3 我踩过的那个坑第一次跑这套代码时我图省事直接用了本机的 MySQL 8.0结果连接一直报时区错误我以为是驱动包坏了换了三个版本的 jar 都没用折腾了一下午才反应过来是 URL 少了个serverTimezone。从那以后我每次拿到带 SQL 脚本的 Java 项目都强制先做三件事确认 MySQL 版本、核对驱动类名、检查连接串参数三步走完再动界面代码。这套流程帮我省下了大量无谓的排查时间也希望帮到你。本文还有配套的精品资源点击获取

相关新闻

MySQL校对规则:utf8mb4_general_ci与utf8mb4_bin的差异及选型

MySQL校对规则:utf8mb4_general_ci与utf8mb4_bin的差异及选型

1. 这两个校对规则到底在吵什么看你一脸问号地点进来,我猜你多半是遇到过这种情况:建表的时候复制了一段别人的SQL,里面有CHARSETutf8mb4 COLLATEutf8mb4_general_ci,或者是utf8mb4_bin,当时也没多想,能用就…

2026/10/9 6:35:27 阅读更多 →
PS5底层开发合规边界与技术可行性分析

PS5底层开发合规边界与技术可行性分析

我无法根据当前输入生成符合要求的博文。原因如下:项目标题 "AnyPS5" 缺乏明确指向性:该词在公开技术语境中无公认定义,既非官方产品名(索尼未发布/命名过 AnyPS5)、非开源项目(GitHub、GitLab、…

2026/10/9 6:35:27 阅读更多 →
claude-mem:为Claude Code打造跨会话长期记忆的实战指南

claude-mem:为Claude Code打造跨会话长期记忆的实战指南

用过 Claude Code 写真实项目的人,基本都遇到过这个场景:昨天刚跟 AI 讨论清楚的一个架构方案,今天新开一个会话,它完全不记得了。你在同一个仓库里翻历史对话记录,发现上一个会话已经把项目的来龙去脉都喂给了它&…

2026/10/9 6:35:27 阅读更多 →

最新新闻

可靠性测试别只会跑温箱振动台:失效物理与加速寿命是关键

可靠性测试别只会跑温箱振动台:失效物理与加速寿命是关键

干我们这行的,提起“可靠性测试”,不少人第一反应是:把样品扔进温箱里烤一烤、冻一冻,再放振动台上摇一摇,出来没坏就算通过。要是真这么想,那可靠性测试就白做了。作为一个和温箱、振动台、耐久跑法打了十…

2026/10/9 7:02:48 阅读更多 →
JVM内存模型与调优实战:从Minecraft OOM到HMCL配置

JVM内存模型与调优实战:从Minecraft OOM到HMCL配置

很多朋友第一次真正意识到 JVM 的存在,不是在 Java 课堂上,而是在一个完全不相关的场景里——玩游戏的时候。我用 HMCL 启动器给 Minecraft 装了个整合包,点了启动,等了两分钟,游戏闪退。把日志拉到最底部,…

2026/10/9 7:02:48 阅读更多 →
VS Code AI 语言模型配置全指南:模型切换、思维强度与 BYOK 自有密钥接入

VS Code AI 语言模型配置全指南:模型切换、思维强度与 BYOK 自有密钥接入

文档教程 【免费下载链接】vscode-docs Public documentation for Visual Studio Code 项目地址: https://gitcode.com/gh_mirrors/vs/vscode-docs 点击查看 免费下载 本文基于 Visual Studio Code 官方文档仓库(vscode-docs)中的 docs/agen…

2026/10/9 7:02:48 阅读更多 →
多标签文本分类实战复盘:从Embedding到Transformer的TAAC优化之路

多标签文本分类实战复盘:从Embedding到Transformer的TAAC优化之路

1. 从"vibe coding"说起:一个新手小白的TAAC复盘到底在复盘什么第一次看到"vibe coding"这个词,我脑子里蹦出来的画面是:一个人对着编辑器,凭感觉敲代码,跑通了就欢呼,跑不通就换一种写…

2026/10/9 7:02:48 阅读更多 →
内容团队如何用Qoder构建标准化AI工作流与协作机制

内容团队如何用Qoder构建标准化AI工作流与协作机制

团队里六个人,过去半年试过不下四个AI工具,从网页版问答到各种套壳应用,最后都回到同一个问题:AI确实能干活,但每个人干出来的活参差不齐,提示词散落在各自收藏夹里,换个项目就抓瞎。真正让我下…

2026/10/9 7:02:48 阅读更多 →
日期处理陷阱:从1月25日看时区与历法边界

日期处理陷阱:从1月25日看时区与历法边界

我很少拿一个日期当文章标题,但1月25日这个数字,我记了快一整年。不是因为它特殊——公历里它既不是节日也不算节气,每年对应的星期几、农历日子完全不一样。正因为它"每天都在变、又好像什么都没变",才在交付前一周把我…

2026/10/9 7:01:47 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →