简介:这是一份基于Java Swing、MySQL与JDBC开发的数据库课程设计人事管理系统源码包,主要面向计算机相关专业完成数据库课程设计或毕业设计的学生,也适合初学者练习桌面应用与MySQL交互。系统包含软件界面,覆盖人事信息管理常用功能,能帮助学习者理解Swing界面搭建、JDBC连接数据库以及SQL建表与数据操作。包内共有24个文件,以11个Java源文件、12张界面运行截图和1个SQL脚本为主,可直观对照界面效果与后端代码;整体压缩包仅143KB,结构简洁,便于快速下载与本地部署。发布者提示运行报错多由数据库版本差异引起,属于基础问题,可自行解决,这一说明也适合排查同类环境问题。目前已有3878人学习下载,说明这份资源对课程设计场景具有一定参考价值。下载后可用SQL脚本初始化数据库,再结合Java代码运行系统,借此梳理数据库课程设计的完整流程。
1. JavaSwing+MySQL+JDBC 人事管理系统:课设落地前先搞懂这三件事
数据库课程设计大概是大学里最需要同时交付代码、演示截图、SQL 脚本三件套的作业。用 JavaSwing 做界面、MySQL 存数据、JDBC 做连接的人事管理系统,恰好把这三样一次占全:登录窗口、员工管理、部门联动,全部是桌面 Java 程序直接操作 MySQL,不依赖 Tomcat,也不写前端页面。
这份资源解压后是 mysql+java 人事管理.zip,里面 src 放 Java 源码,images 放窗口图标和按钮图,sql 目录下是 databaseproject.sql 建库脚本。比较实在的一点是,资源自带说明里就写了:报的错误基本都是数据库版本不同造成的基础问题。也就是说代码没绕弯子,适合拿来复现、改造,再补上自己的亮点。
适合谁用?正在做数据库课程设计或 Java 课程设计的学生,以及想找一个完整 Swing+JDBC CRUD 链路做参考的初学者。后面几章按「工程结构 → JDBC 连接 → 界面联动 → 避坑 → 进阶」的顺序,把这个资源从能打开到能答辩讲清楚。
2. 工程结构与 SQL 落地:导入脚本前先看清 src、images、sql 的分工
很多同学拿到压缩包第一件事就是双击开发工具把 src 整个拖进去,结果图标丢失、表不存在、连接报错,一个接一个。其实先花十分钟把三个目录看懂,后面能省一晚上的排错时间。
2.1 压缩包内部结构:src、images、sql 目录各自承担什么
解压后典型目录结构如下:
mysql+java人事管理/ ├── src/ # Java 源码 │ ├── view/ # Swing 界面类:登录窗、主窗体、员工管理 │ ├── dao/ # 数据访问类:员工、部门、登录校验 │ └── util/ # DBHelper 等连接工具 ├── images/ # 窗口图标、按钮背景图、logo └── sql/ └── databaseproject.sql # 建库建表脚本src 目录是代码主体,view 放 JFrame 和 JPanel,dao 放 JDBC 操作,util 放连接工具类。images 目录很容易被忽略,但 Swing 界面如果引用了图片,路径不对会直接空指针,或者按钮上不显示任何图标。sql 目录下的 databaseproject.sql 是整个项目的根基——没有它,后面所有查询都会因为表不存在而失败。
改动优先级上看,如果你只想改项目名、表名、加字段,动 src/dao 和 sql 就够了;想换皮肤或改图标再动 images;view 层一般只改按钮事件里的逻辑。
2.2 建库脚本导入:字段类型、字符集和外键一起处理
以 Windows 下 MySQL 8.0 为例,先启动服务,再命令行登录并导入:
mysql -u root -p source D:/course/mysql+java人事管理/sql/databaseproject.sql;用 Navicat 也可以,新建连接后右键运行 SQL 文件。脚本里的建表语句通常是这个风格:
CREATE DATABASE IF NOT EXISTS hrm DEFAULT CHARACTER SET utf8mb4; USE hrm; CREATE TABLE tb_dept ( dept_id INT PRIMARY KEY AUTO_INCREMENT, dept_name VARCHAR(50) NOT NULL UNIQUE, remark VARCHAR(200) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE tb_employee ( emp_id INT PRIMARY KEY AUTO_INCREMENT, emp_no VARCHAR(20) NOT NULL UNIQUE, emp_name VARCHAR(30) NOT NULL, gender CHAR(2) DEFAULT '男', dept_id INT, position VARCHAR(50), hire_date DATE, salary DECIMAL(10,2), phone VARCHAR(20), CONSTRAINT fk_emp_dept FOREIGN KEY (dept_id) REFERENCES tb_dept(dept_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;表名、字段名以你解压出来的 databaseproject.sql 实际内容为准,我列的是人事管理课设最常见结构。参数说明:emp_no 用 VARCHAR(20) 是因为员工编号不一定是纯数字,可能带字母前缀;hire_date 用 DATE 取值直观,JDBC 读取时对应 java.sql.Date;salary 用 DECIMAL(10,2),整数部分最大 99999999.99,课设工资数据完全够用;gender 用 CHAR(2) 是因为「男/女」正好占两个字符。外键 fk_emp_dept 在评审时是加分项,它保证员工不能插入不存在的部门。
导入后确认库里能看到三张以上的表:tb_admin(登录用)、tb_dept(部门)、tb_employee(员工)。如果只看到一个空库,大概率是脚本没执行完,或者执行了但没有切到目标库。
2.3 用 Navicat 还是命令行:课设环境下我推荐的导入路径
单纯导入脚本,命令行和 Navicat 都能完成,差别在排错效率。命令行 source 导入能看到每一条 SQL 的执行结果,语法错误和字段类型不兼容会明确告诉你第几行有问题,这是 Navicat 做不到的。
我的建议是:第一次用命令行 source,确认脚本没问题;之后再用 Navicat 运行 SQL 文件,速度快。如果执行到一半报错,先检查脚本里有没有多余的注释,或者 MySQL 版本语法差异。
MySQL 5.x 和 8.x 在这里就已经出现第一个差异:8.x 默认认证方式是 caching_sha2_password,老版本 JDBC 驱动连上来会被拒绝认证。这个坑在第 5 章会专门讲,这里先记住一个原则:驱动版本尽量和数据库版本对应,不要拿 mysql-connector 5.1 硬连 MySQL 8.0。
3. JDBC 连接与 DAO 层:把增删改查写稳,课设就过了一半
3.1 驱动加载与连接参数:mysql 5.x 和 8.x 之间的三个差异
在人事管理系统里,所有界面按钮最终都要落成 SQL 执行。而连接数据库这一步,大多数人第一次跑不通都卡在这三个差异上。
第一,驱动类名。MySQL 5.x 用 com.mysql.jdbc.Driver,8.x 改成了 com.mysql.cj.jdbc.Driver。第二,URL 参数。8.x 必须带 serverTimezone,否则报时区错误。第三,SSL 与公钥。本地课设一般直接 useSSL=false,但 8.x 还可能遇到 Public Key Retrieval 问题,对应解决方案在第 5 章。
下面是这个资源里 DBHelper 工具类的常见写法:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class DBHelper { // MySQL 8.x 用 com.mysql.cj.jdbc.Driver;MySQL 5.x 用 com.mysql.jdbc.Driver private static final String DRIVER = "com.mysql.cj.jdbc.Driver"; private static final String URL = "jdbc:mysql://localhost:3306/hrm" + "?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8"; 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 main(String[] args) throws SQLException { try (Connection conn = getConnection()) { System.out.println("连接成功:" + conn.getMetaData().getDatabaseProductName()); } } }代码逻辑说明:Class.forName(DRIVER) 在类加载时向 DriverManager 注册驱动。虽然新版本 JDBC 驱动不写也能自动注册,但保留这一行能让 5.x/8.x 之间切换更稳。getConnection() 每次调用都新建物理连接,课设数据量小没有性能压力;到第 6 章会把这个位置替换成连接池。
参数说明:localhost:3306/hrm 是 MySQL 地址、端口、库名,库名必须和建库脚本里的 USE hrm 一致;useSSL=false 关闭 SSL 加密,本地开发不需要;serverTimezone=Asia/Shanghai 解决 8.x 时区报错;characterEncoding=utf8 配合表结构的 utf8mb4 保证中文不乱码。USER 和 PASSWORD 写你自己本机的账号,不是资源自带的,这是连接失败最高频的原因。
写一个带 main 方法的测试类是最快的验证方式,控制台输出「连接成功」以后再做 DAO 层。
3.2 PreparedStatement 参数绑定:为什么增删改都推荐它
DAO 层代码在 src/dao 目录下,负责员工新增、修改、删除、查询。用 Statement 拼接 SQL 虽然短,但字符串里出现单引号会让 SQL 直接语法错误,甚至造成 SQL 注入。PreparedStatement 在驱动层预编译,参数用占位符 ? 传入,既避免了拼接问题,又挡住了注入。
以新增员工为例:
public boolean addEmployee(Employee emp) { String sql = "INSERT INTO tb_employee(emp_no, emp_name, gender, dept_id, " + "position, hire_date, salary, phone) VALUES(?,?,?,?,?,?,?,?)"; try (Connection conn = DBHelper.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setString(1, emp.getEmpNo()); ps.setString(2, emp.getEmpName()); ps.setString(3, emp.getGender()); ps.setInt(4, emp.getDeptId()); ps.setString(5, emp.getPosition()); // 界面拿到的是 java.util.Date,JDBC 需要 java.sql.Date ps.setDate(6, emp.getHireDate() != null ? new java.sql.Date(emp.getHireDate().getTime()) : null); ps.setBigDecimal(7, emp.getSalary()); ps.setString(8, emp.getPhone()); return ps.executeUpdate() > 0; } catch (SQLException e) { e.printStackTrace(); return false; } }逻辑说明:先写 SQL,八个 ? 对应八个字段,然后按下标顺序 set 值。setDate 值得单独说,Swing 界面拿到的通常是 java.util.Date,而 JDBC 只接受 java.sql.Date,所以这里用 new java.sql.Date(emp.getHireDate().getTime()) 做转换;如果 hireDate 为 null,直接传 null 不会触发空指针。
参数说明:executeUpdate() 返回受影响行数,插入成功返回 1,所以返回 true;SQL 字段和表结构对不上会抛 SQLException,打印堆栈后返回 false。try-with-resources 写法让 Connection、Statement 自动关闭,不会留下连接泄漏。这段代码在整个课程设计里几乎可以复制到所有写操作上。
3.3 员工列表查询:ResultSet 到对象的映射习惯
查询和更新不同,执行 executeQuery() 拿到 ResultSet,这是一个只能向前移动的行指针,必须用 rs.next() 逐行遍历。常见的映射习惯是把数据库行转成 Employee 对象再放进 List,界面层不直接接触 ResultSet:
public List<Employee> listEmployees() { String sql = "SELECT e.*, d.dept_name FROM tb_employee e " + "LEFT JOIN tb_dept d ON e.dept_id = d.dept_id " + "ORDER BY e.emp_id"; List<Employee> list = new ArrayList<>(); try (Connection conn = DBHelper.getConnection(); PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery()) { while (rs.next()) { Employee e = new Employee(); e.setEmpId(rs.getInt("emp_id")); e.setEmpNo(rs.getString("emp_no")); e.setEmpName(rs.getString("emp_name")); e.setGender(rs.getString("gender")); e.setDeptName(rs.getString("dept_name")); e.setPosition(rs.getString("position")); e.setHireDate(rs.getDate("hire_date")); e.setSalary(rs.getBigDecimal("salary")); e.setPhone(rs.getString("phone")); list.add(e); } } catch (SQLException ex) { ex.printStackTrace(); } return list; }这段 SQL 用了 LEFT JOIN,因为员工可能还没分配部门,用 INNER JOIN 会把没部门的员工过滤掉,列表数量对不上的时候很容易漏查这个原因。getDate("hire_date") 返回的是 java.sql.Date,它是 java.util.Date 的子类,所以 Employee 里用 java.util.Date 接收没有任何问题。getBigDecimal 对应数据库的 DECIMAL,精确计算不会像 double 那样丢精度。
到这里,登录和员工管理背后需要的 JDBC 能力已经齐了:连接、插入、查询。修改和删除是同一套写法,把 SQL 换成 UPDATE、DELETE,参数绑定顺序对应 WHERE 条件即可。下一步是回到 Swing 界面,把这些方法挂到按钮上。
4. Swing 界面与业务联动:登录、表格、表单三条链路怎么串
4.1 登录判断:密码必须在后端校验
人事管理系统的登录窗口是 JFrame,用户名用 JTextField、密码用 JPasswordField。前端校验只能拦空值,真正判断要看数据库里有没有这条管理员记录。
loginButton.addActionListener(e -> { String username = usernameField.getText().trim(); String pwd = new String(passwordField.getPassword()); if (username.isEmpty() || pwd.isEmpty()) { JOptionPane.showMessageDialog(loginFrame, "用户名和密码不能为空"); return; } if (adminDao.checkLogin(username, pwd)) { loginFrame.dispose(); new MainFrame().setVisible(true); } else { JOptionPane.showMessageDialog(loginFrame, "用户名或密码错误,请重试"); } });adminDao 里的 checkLogin 方法关注两点。第一,密码用 getPassword() 拿字符数组再转字符串,而不是 getText(),这是 Swing 的一个安全习惯,避免密码以 String 形式常驻内存;第二,SQL 查询写成 SELECT COUNT(*) FROM tb_admin WHERE username=? AND password=?,返回的 count 大于 0 就放行。
这段代码里最容易被忽略的是 loginFrame.dispose(),主窗口显示前先销毁登录窗口,否则关掉登录窗口程序还留在后台,答辩演示切窗口时会很尴尬。登录这块就这么短,但它把界面、DAO、数据库三层全部串起来了。
4.2 JTable 与 DefaultTableModel:查询结果怎么进表格
主窗口里的员工列表基本都用 JTable,它本身不存数据,数据放在 TableModel 里。DefaultTableModel 是最常用实现,构造参数是列名数组和初始行数 0。
DefaultTableModel model = new DefaultTableModel( new Object[]{"编号", "姓名", "性别", "部门", "职位", "入职日期", "工资", "电话"}, 0); List<Employee> employees = empDao.listEmployees(); for (Employee e : employees) { model.addRow(new Object[]{ e.getEmpNo(), e.getEmpName(), e.getGender(), e.getDeptName(), e.getPosition(), e.getHireDate(), e.getSalary(), e.getPhone() }); } empTable.setModel(model);参数说明:DefaultTableModel 构造器的第二个参数 0 代表初始行数,然后逐行 addRow;第一个参数 Object[] 直接决定表格的列数量,列位置和 addRow 数组顺序一一对应。工资列是 BigDecimal,表格单元格默认显示不带两位小数,可以重写 getColumnClass 或做格式化,但课设标准下直接显示足够。
列太窄会影响答辩观感,建议顺手设置一下宽度和单选模式:
empTable.getColumnModel().getColumn(0).setPreferredWidth(80); empTable.getColumnModel().getColumn(1).setPreferredWidth(100); empTable.getColumnModel().getColumn(7).setPreferredWidth(120); empTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);刷新逻辑有一点血泪经验:每次重新查询前先执行 model.setRowCount(0),否则上一次的数据还留在模型里,新数据追加到尾部,表格越刷越长,看起来像重复数据。还有一点相关的坑:如果表格上的数据需要点击排序,可以调用 setAutoCreateRowSorter(true),但排序后 getSelectedRow 拿到的是视图行的索引,取值前需要做 convertRowIndexToModel 转换,不然删除时容易删错行。
4.3 新增、修改、删除按钮的事件边界
Swing 是事件驱动单线程模型,按钮点击里直接调 DAO 方法就行,不需要开子线程。删除场景要记住顺序:先校验有没有选中行,再弹确认框,最后才执行删除。
deleteButton.addActionListener(e -> { int row = empTable.getSelectedRow(); if (row < 0) { JOptionPane.showMessageDialog(frame, "请先选中要删除的行"); return; } String empNo = model.getValueAt(row, 0).toString(); int confirm = JOptionPane.showConfirmDialog(frame, "确认删除编号为 " + empNo + " 的员工?", "删除确认", JOptionPane.YES_NO_OPTION); if (confirm == JOptionPane.YES_OPTION && empDao.deleteByEmpNo(empNo)) { model.setRowCount(0); loadData(); JOptionPane.showMessageDialog(frame, "删除成功"); } });注意这里删除条件用的是 emp_no 而不是主键 emp_id。员工编号在表里有 UNIQUE 索引,业务上用它定位更直观。修改同理,UPDATE 语句的 WHERE 条件必须带主键或唯一键,否则可能把全表的数据都改了——这个坑在课设答辩里被问到的概率不低。
新增和修改通常弹一个 JDialog 表单,把文本框内容读出来封装成 Employee 对象,分别调 dao.addEmployee 和 dao.updateEmployee。一个容易忽略的小问题是日期输入框,JTextField 读出来是字符串,插入前必须按 yyyy-MM-dd 解析成 java.sql.Date,否则 5.5 节那种 Incorrect date value 就会找上门。
核心经验是:界面只负责取值和提示,数据库操作全部收敛在 DAO 层。这样后续做答辩演示时,改界面、换数据库都比较从容。
5. 部署与排查:人事管理系统最常见的五个翻车现场
这个资源自带的说明里提过,它报的错误都是一些基础错误,因为数据库版本不同造成的。下面这几条是我在部署同类 Swing+JDBC 项目时见过最多的,也是翻车概率最高的五个点。
5.1 Public Key Retrieval is not allowed
现象:主程序第一次执行数据库查询时抛 SQLNonTransientConnectionException,堆栈里明确写着 Public Key Retrieval is not allowed。
原因:MySQL 8.0 默认用 caching_sha2_password 做用户认证。客户端第一次连接时如果没有 SSL 加密,服务端要求先获取 RSA 公钥用于密码加密,而 JDBC 驱动出于安全考虑默认禁止自动获取公钥。
解决:在 URL 末尾加 allowPublicKeyRetrieval=true。完整连接串变成 jdbc:mysql://localhost:3306/hrm?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8。如果还报同样的错,把驱动 jar 换到 mysql-connector-java 8.0.16 以上,早期版本对这个参数支持不完整。
5.2 ClassNotFoundException: com.mysql.jdbc.Driver
现象:运行程序时控制台直接抛 ClassNotFoundException,报错信息是 com.mysql.jdbc.Driver。
原因:驱动类名和 jar 版本不匹配。MySQL 8.x 的驱动类名已经改成 com.mysql.cj.jdbc.Driver,代码里写的还是 5.x 的类名;另一种情况是 jar 包根本没进 classpath,编译器找不到。
解决:先确认 MySQL 版本。如果是 8.x,把 DBHelper 里的 DRIVER 改成 com.mysql.cj.jdbc.Driver,并在 lib 目录放 mysql-connector-java-8.0.x.jar;如果是 5.x,保留老驱动即可。jar 放进项目后一定要右键 Add to Build Path 或 Add as Library,只拖进目录而不加构建路径,编译器照样找不到,这个问题在答辩前最容易临时爆出来。
5.3 中文乱码
现象:员工姓名、部门名称在数据库和界面里显示成 ?? 或乱码。
原因:乱码是三层不一致导致的:MySQL 连接 URL 没有指定字符集、建表字段不是 utf8mb4、SQL 脚本文件本身保存成 ANSI 编码。任何一层不对,中文就会在导入或查询时变形。
解决:按顺序排查。先给 URL 加 characterEncoding=utf8;再确认建库语句里有 DEFAULT CHARACTER SET utf8mb4;最后确认导入给 MySQL 的 SQL 脚本文件是用 UTF-8 保存的。做完这三点,中文乱码基本不会出现。如果开发工具里界面乱码,在启动参数 VM options 里加 -Dfile.encoding=UTF-8 然后重启项目即可。
5.4 开发工具里找不到 jar 包
现象:代码里 import java.sql.* 正常,但 DriverManager 或 Class.forName 报红线,运行时报 ClassNotFoundException。
原因:驱动 jar 没有正确加入项目构建路径;或者用 Maven 自动下载依赖时因网络问题失败,控制台出现 download from maven failed 这类提示。
解决:课设阶段建议直接绕开 Maven,去 MySQL 官网或中央仓库下载对应版本的 mysql-connector-java.jar,放进项目根目录下的 lib 文件夹,然后右键 Build Path → Add to Build Path。IDEA 里选中 jar 后右键 Add as Library。如果坚持用 Maven,把下载源切到阿里云镜像再刷新依赖。手工加 jar 虽然原始,但解决「找不到类」这类问题的速度是最快的。
5.5 日期和字段类型不匹配
现象:新增员工时 executeUpdate 抛 SQLException,常见信息是 Incorrect date value 或 Data too long。有些错误更隐蔽,插入成功但日期显示成 0000-00-00。
原因:两个点。界面传的日期是 java.util.Date 或字符串,JDBC 需要 java.sql.Date,不转换直接 setDate 会在类型转换阶段出错;另外字段长度不够,比如 VARCHAR(10) 存 11 位手机号,或 DATE 字段收到了带时间格式的字符串。
解决:setDate 之前统一转成 java.sql.Date,代码写法在 3.2 节已经给出。手机号、身份证这类字段在表设计阶段就放宽到 VARCHAR(30),避免数据处理时被截断。还有一个习惯:从 JTextField 读日期字符串时先按 yyyy-MM-dd 做校验,格式不对直接弹提示,不让脏数据进 SQL。
如果上面五条都没命中,把堆栈里 SQLException 那行复制出来看提示。常见还有:数据库端口 3306 被占用、密码错误导致 Access denied for user 'root'@'localhost'、表名与 Java 代码里的 SQL 大小写不一致。其中表名大小写的问题在 Windows 开发机上不容易暴露,因为 Windows 表名默认不区分大小写,一旦部署到 Linux 或 macOS,大小写不一致直接报 Table doesn't exist。我习惯在交项目之前,用命令行执行一条 SELECT * FROM tb_employee 验证表名真实存在,这一步能过滤掉很多隐藏问题。
6. 进阶验证:用数据库连接池替换 DriverManager 并做功能自测
6.1 连接池改造:Druid 替换 DriverManager 的最小改动
课设代码跑通后,如果想在答辩时加一个技术亮点,我一般会建议把 DBHelper 里的 DriverManager 换成 Druid 连接池。改动量很小,效果却很直观:不用每次查询都重新建立物理连接,员工列表刷新会快很多。
先引入 druid-1.2.x.jar,再参考下面的写法:
import com.alibaba.druid.pool.DruidDataSource; import java.sql.Connection; import java.sql.SQLException; public class DruidHelper { private static DruidDataSource dataSource; static { dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/hrm" + "?useSSL=false&serverTimezone=Asia/Shanghai"); dataSource.setUsername("root"); dataSource.setPassword("123456"); dataSource.setInitialSize(3); dataSource.setMaxActive(10); } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } }关键参数:initialSize=3 表示启动时就建 3 个连接备用,maxActive=10 是最大连接数。课设并发量低,这两个值已经足够。替换时把 DAO 里所有 DBHelper.getConnection() 改成 DruidHelper.getConnection() 就行,DAO 层其他代码一行不用动。第一次跑容易踩 jar 包冲突,确认 druid 和 mysql connector 两个 jar 都在构建路径里再运行。
6.2 功能自测清单:答辩前快速过一遍
替换连接池之后,我习惯在交作业前按下面的清单完整走一遍:
| 模块 | 操作 | 预期结果 |
|---|---|---|
| 登录 | 输入正确账号密码 | 进入主窗体 |
| 登录 | 输入错误密码 | 弹提示,不崩溃 |
| 员工管理 | 新增一条员工记录 | 表格立即刷新出现新行 |
| 员工管理 | 删除选中员工 | 有确认框,确认后行消失 |
| 边界数据 | 手机号输入 11 位数字 | 正常保存不截断 |
| 边界数据 | 输入 ' or '1'='1 查询 | 结果为空,不泄露数据 |
这套流程我每次拿到新的课设资源都会强制走一遍,因为它把连接、CRUD、边界处理全部覆盖到了。从那次在一台 MySQL 8 机器上被 Public Key 问题卡了两个小时之后,我就养成了习惯:拿到任何 Swing+JDBC 项目,先看数据库版本和驱动版本是否匹配,再跑登录,最后测一次 SQL 注入。
希望这份人事管理系统的拆解能帮到你,把踩坑时间省下来,用到真正该用的地方。
本文还有配套的精品资源,点击获取