
简介这份资源是一套基于 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 版本、核对驱动类名、检查连接串参数三步走完再动界面代码。这套流程帮我省下了大量无谓的排查时间也希望帮到你。本文还有配套的精品资源点击获取