尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Java Swing+MySQL工资管理系统实战教程

Java Swing+MySQL工资管理系统实战教程 简介本资源是一套基于Java Swing与MySQL开发的员工工资管理系统完整实现面向计算机专业本科生及Java初学者适用于Java课程设计、期末大作业等实践教学场景。系统功能覆盖员工信息管理、部门维护、工资核算、查询统计与密码修改等核心模块代码结构清晰、注释规范已通过本地编译验证并获98分高分评审具备良好的学习参考价值与工程可复现性。压缩包共47个文件含12个Java业务逻辑类、10个XML配置与界面布局文件、5个SQL建表与数据初始化脚本、13张操作界面截图如add.png、query.png、modify.png等以及jar依赖库和项目配置文件整体大小为2.99MB。目前已有153人下载学习配套文档说明详实目录组织合理便于理解MVC分层思想、Swing事件驱动机制及JDBC数据库交互全流程。1. 这不是又一个“Hello World”Swing界面它是一套能跑通完整工资核算闭环的Java桌面系统你可能已经点开过十几个标着“Java课程设计”的Swing项目双击jar包后弹出一个带登录框的窗口输完账号密码——然后卡在“查询中…”再无下文。而这个Goat_SalaryManageSystem-SMS不同它在本地 MySQL 8.0.26 环境下实测可完成「部门录入 → 员工建档 → 基础薪资配置 → 考勤扣减计算 → 工资条生成 → Excel导出」全链路评审分98分不是虚的。它没用 Spring Boot 做后端也没上 Web 前端框架而是用纯 Swing 组件JDBC 直连 MySQL把 JDBC 的事务控制、ResultSet 映射、Swing 事件驱动与 UI 状态同步这些 Java SE 核心能力扎扎实实串成一条线。适合正在啃《Java核心技术卷I》第10章Swing和第12章JDBC的本科生也适合想快速复现一个“非玩具级”桌面应用的转行者——它不炫技但每个按钮背后都有 try-catch 包裹的 PreparedStatement 执行逻辑每张表格都对应着真实字段映射的 TableModel 实现。2. 为什么选 Swing MySQL 8.0.26 而不是 JavaFX 或 SQLite2.1 技术栈选择背后的教学刚性约束课程设计明确要求“使用 Java 原生 GUI 库与关系型数据库”这直接排除了 JavaFX需额外模块声明、WebView依赖浏览器内核和嵌入式数据库如 HSQLDB。Swing 是 JDK 8~17 自带、零依赖、组件生命周期清晰的唯一选项MySQL 则因学校机房统一部署、助教熟悉其权限管理与备份机制成为事实标准。特别注意本项目强制绑定mysql-connector-java-8.0.26.jar而非最新版 8.3.x原因在于后者默认启用sslModeREQUIRED而本地开发环境常未配置 SSL 证书会导致Communications link failure。这是学生最容易卡住的第一道墙。提示若启动时报java.sql.SQLException: Unknown system variable caching_sha2_password说明 MySQL 8.0 默认认证插件不兼容旧驱动。解决方案不是降级 MySQL而是执行以下 SQL 切换用户认证方式ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY your_password; FLUSH PRIVILEGES;此命令将 root 用户认证方式从caching_sha2_password切回mysql_native_password与 8.0.26 驱动完全兼容。2.2 数据库初始化脚本的三层结构解析项目中init.sql、gongzi.sql、gongzi_beifen.sql并非简单重复而是承担不同职责脚本名作用关键内容使用时机init.sql创建基础库表结构与初始数据CREATE DATABASE IF NOT EXISTS salary_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;CREATE TABLE department(...)首次部署时执行建立空库gongzi.sql插入典型业务数据样本INSERT INTO employee (id, name, dept_id, base_salary) VALUES (1001, 张三, 1, 8500.00);初始化后立即执行填充测试数据gongzi_beifen.sql全量数据备份含自增主键值INSERT INTO employee VALUES (1001,张三,1,8500.00,...), (1002,李四,2,7200.00,...);用于恢复误删数据保留原始 ID 序列执行顺序必须是先运行init.sql创建库表 → 再运行gongzi.sql插入数据。若跳过init.sql直接执行gongzi.sql会因表不存在报错若用gongzi_beifen.sql替代gongzi.sql则因包含INSERT ... VALUES (...)全量语句在已有数据时触发主键冲突。2.3 Swing UI 层的组件化拆解与状态管理整个系统 UI 由src/sdms/ui/下 12 个.java文件构成每个文件对应一个功能面板如AddEmployeePanel.java、SalaryQueryPanel.java。关键设计在于MainForm.java中的卡片布局CardLayout管理// MainForm.java 片段 private CardLayout cardLayout; private JPanel contentPanel; public MainForm() { contentPanel new JPanel(); cardLayout new CardLayout(); contentPanel.setLayout(cardLayout); // 添加所有功能面板以字符串为标识符 contentPanel.add(new LoginPanel(this), login); contentPanel.add(new MainDashboardPanel(this), dashboard); contentPanel.add(new AddEmployeePanel(this), addEmployee); contentPanel.add(new QuerySalaryPanel(this), querySalary); // ... 其他面板 }所有面板通过this引用传递MainForm实例实现跨面板通信。例如点击“查询工资”按钮时MainDashboardPanel调用// MainDashboardPanel.java private void onQueryClick() { mainForm.showCard(querySalary); // 切换到查询面板 queryPanel.loadAllEmployees(); // 触发数据加载 }这种设计避免了全局静态变量符合 Swing 单线程规则所有 UI 更新必须在 Event Dispatch Thread 中执行也便于单元测试——每个面板可独立实例化并注入 mock 的MainForm。3. 从零部署JDK、MySQL、IDE 三环境联调实操指南3.1 JDK 8u2XX 环境验证与 CLASSPATH 构建本项目编译目标为1.8需确认 JDK 版本java -version # 输出应为java version 1.8.0_381 或类似 javac -version # 输出应为javac 1.8.0_381若版本不符需设置JAVA_HOME并更新PATH。重点检查CLASSPATH是否包含所有依赖 JAR# Linux/macOS 检查方式Windows 类似 echo $CLASSPATH # 正确输出应包含项目根目录下的 lib/ 路径例如 # /path/to/Goat_SalaryManageSystem-SMS/lib/jxl.jar:/path/to/.../lib/mysql-connector-java-8.0.26.jar若缺失需在 IDE 或命令行中显式添加。IntelliJ IDEA 中操作路径File → Project Structure → Modules → Dependencies → → JARs or directories选择lib/文件夹。3.2 MySQL 8.0.26 本地服务配置要点仅安装 MySQL 不够必须完成三项配置3.2.1 创建专用数据库用户非 root直接用 root 连接存在安全风险且部分学校机房禁用 root 远程登录。创建最小权限用户-- 登录 MySQL 后执行 CREATE USER sms_userlocalhost IDENTIFIED BY StrongPass123!; CREATE DATABASE salary_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; GRANT SELECT, INSERT, UPDATE, DELETE ON salary_db.* TO sms_userlocalhost; FLUSH PRIVILEGES;此用户仅对salary_db拥有 CRUD 权限无法创建库或查看其他数据库。3.2.2 修改 MySQL 配置文件启用远程访问可选若需从其他机器访问如宿舍电脑连实验室服务器编辑my.cnfLinux或my.iniWindows[mysqld] bind-address 0.0.0.0 # 允许所有 IP 访问 port 3306 # 确保 skip-networking 未启用重启 MySQL 服务后用sms_user账号从外部连接测试mysql -h 192.168.1.100 -P 3306 -u sms_user -p salary_db3.2.3 验证 JDBC 连接字符串有效性项目中数据库连接配置位于src/sdms/db/DatabaseConnection.javaprivate static final String URL jdbc:mysql://localhost:3306/salary_db?useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue; private static final String USER sms_user; private static final String PASSWORD StrongPass123!;参数含义useSSLfalse禁用 SSL解决 8.0.26 驱动兼容性问题serverTimezoneAsia/Shanghai避免The server time zone value ... is unrecognized错误allowPublicKeyRetrievaltrue配合mysql_native_password认证方式注意若修改了 MySQL 端口如改为 3307必须同步修改URL中的:3306部分否则连接超时。3.3 IntelliJ IDEA 导入与运行配置导入步骤不能直接Open项目根目录必须按 Maven 结构识别启动 IDEA →Open→ 选择Goat_SalaryManageSystem-SMS文件夹当提示 “Import project from external model” 时勾选 “Create project from existing sources”因本项目无 pom.xml非 Maven 项目在Project SDK步骤中选择已安装的 JDK 1.8完成后右键src/sdms/GoatSalaryManageSystem.java→Run GoatSalaryManageSystem.main()若首次运行报ClassNotFoundException: com.mysql.cj.jdbc.Driver说明mysql-connector-java-8.0.26.jar未加入模块依赖右键项目 →Open Module Settings→Modules→Dependencies→→JARs or directories→ 选择lib/mysql-connector-java-8.0.26.jar4. 核心业务逻辑深度解析工资计算引擎如何规避浮点数精度陷阱4.1 工资条生成中的 BigDecimal 实战应用员工月工资 基本工资 绩效奖金 补贴 - 社保扣款 - 个税 - 缺勤扣款。若用double计算8500.50 2000.00 - 1200.35可能产生9299.149999999999导致银行代发失败。本项目在src/sdms/model/SalaryCalculator.java中全程使用BigDecimalpublic class SalaryCalculator { private static final MathContext MC new MathContext(2, RoundingMode.HALF_UP); public BigDecimal calculateTotalSalary(Employee emp, AttendanceRecord att) { BigDecimal base new BigDecimal(emp.getBaseSalary().toString()); BigDecimal bonus new BigDecimal(emp.getBonus().toString()); BigDecimal allowance new BigDecimal(emp.getAllowance().toString()); BigDecimal deduction calculateDeductions(emp, att); return base.add(bonus).add(allowance).subtract(deduction, MC); } private BigDecimal calculateDeductions(Employee emp, AttendanceRecord att) { BigDecimal socialSecurity new BigDecimal(emp.getSocialSecurity().toString()); BigDecimal tax calculateTax(base.add(bonus).add(allowance)); BigDecimal absence calculateAbsenceDeduction(att); return socialSecurity.add(tax).add(absence); } }关键点所有double字段如baseSalary在参与计算前必须通过toString()转为BigDecimal避免new BigDecimal(8500.50)因二进制浮点表示误差引入8500.499999999999MathContext(2, RoundingMode.HALF_UP)确保所有中间结果保留 2 位小数并四舍五入如1200.345→1200.35subtract(deduction, MC)显式传入 MathContext保证减法也遵循相同精度规则4.2 Excel 导出模块的 jxl.jar 兼容性处理项目使用jxl.jarJExcelAPI导出工资条为.xls格式因其轻量且无需 Office 环境。但该库已停止维护与 JDK 9 的模块化存在冲突。解决方案是在src/sdms/util/ExcelExporter.java中添加异常兜底public void exportToExcel(ListSalaryRecord records, String filePath) { try (WritableWorkbook workbook Workbook.createWorkbook(new File(filePath))) { WritableSheet sheet workbook.createSheet(工资明细, 0); // 写入表头与数据... workbook.write(); } catch (IOException e) { // JDK 9 模块化导致的 AccessControlException 兜底 if (e instanceof java.security.AccessControlException) { JOptionPane.showMessageDialog(null, 导出失败JDK 版本过高请使用 JDK 8 运行本程序, Excel 导出错误, JOptionPane.ERROR_MESSAGE); } throw new RuntimeException(Excel 导出异常, e); } }提示若需支持.xlsx格式可替换为 Apache POI但会增加 5MB 以上 JAR 体积违背课程设计“轻量可控”原则。4.3 Swing 表格数据刷新的线程安全实践当用户在QuerySalaryPanel中点击“刷新”按钮时后台查询可能耗时 200ms。若直接在 EDTEvent Dispatch Thread中执行 JDBC 查询UI 将冻结。项目采用SwingWorker实现异步加载private void refreshTable() { // 禁用按钮防止重复提交 refreshButton.setEnabled(false); statusLabel.setText(加载中...); SwingWorkerListSalaryRecord, Void worker new SwingWorker() { Override protected ListSalaryRecord doInBackground() throws Exception { // 在后台线程执行耗时的 JDBC 查询 return salaryService.queryAllSalaries(); } Override protected void done() { try { ListSalaryRecord data get(); // 获取 doInBackground 返回值 tableModel.setData(data); // 更新 TableModel statusLabel.setText(共 data.size() 条记录); } catch (Exception e) { JOptionPane.showMessageDialog(null, 查询失败 e.getMessage()); } finally { refreshButton.setEnabled(true); } } }; worker.execute(); // 启动异步任务 }此模式确保 UI 响应性且done()方法自动在 EDT 中执行可安全更新tableModel和statusLabel。5. 故障排查手册5 类高频报错的定位与修复路径5.1 连接 MySQL 失败的逐层诊断表当DatabaseConnection.getConnection()抛出异常时按此顺序排查报错信息关键词可能原因验证命令修复动作Communications link failureMySQL 服务未启动或端口被占用netstat -an | grep 3306Linuxtelnet localhost 3306Windows启动 MySQL 服务sudo systemctl start mysqldCentOSbrew services start mysqlmacOSUnknown database salary_dbinit.sql未执行或执行失败mysql -u root -p -e SHOW DATABASES;手动执行mysql -u root -p init.sqlAccess denied for user sms_userlocalhost用户密码错误或权限不足mysql -u root -p -e SELECT User,Host FROM mysql.user;重置密码ALTER USER sms_userlocalhost IDENTIFIED BY newpass;No suitable driver found for jdbc:mysql://...mysql-connector-java-8.0.26.jar未加载查看 IDEAProject Structure → Libraries将 JAR 拖入lib/文件夹并重新添加为依赖The server time zone value ... is unrecognizedMySQL 时区配置与 JDBC 参数不匹配mysql -u root -p -e SELECT global.time_zone, session.time_zone;在 JDBC URL 中添加serverTimezoneAsia/Shanghai5.2 Swing 界面乱码与图标缺失的根因分析中文显示为方块、按钮图标不出现本质是资源路径与类加载器问题5.2.1 中文乱码字体渲染异常根本原因是 JVM 启动参数未指定字体配置。在 IDEA 运行配置中添加 VM options-Dfile.encodingUTF-8 -Dsun.jnu.encodingUTF-8 -Dawt.useSystemAAFontSettingslcd若仍无效在MainForm.java构造函数中强制设置系统字体UIManager.put(Label.font, new Font(Microsoft YaHei, Font.PLAIN, 14)); UIManager.put(Button.font, new Font(Microsoft YaHei, Font.BOLD, 14)); SwingUtilities.updateComponentTreeUI(this); // 刷新所有组件5.2.2 图标文件PNG加载失败项目中image/文件夹存放 15 个 PNG 按钮图标加载代码为ImageIcon icon new ImageIcon(getClass().getResource(/image/add.png));常见失败原因image/文件夹未被 IDEA 识别为资源根目录 → 右键image→Mark Directory as → Resources Root图标文件名大小写错误Linux 区分大小写→ 检查add.png是否实际为Add.pnggetResource()返回 null → 在加载处添加判空URL iconUrl getClass().getResource(/image/add.png); if (iconUrl null) { System.err.println(图标未找到/image/add.png请检查 resources 目录结构); icon new ImageIcon(); // 返回空图标避免 NPE } else { icon new ImageIcon(iconUrl); }5.3 编译报错package javax.swing does not exist的终极解法此错误表明编译器未识别 Swing API通常因 JDK 配置错误IDEA 中File → Project Structure → Project → Project SDK必须指向 JDK非 JRE安装路径如/Library/Java/JavaVirtualMachines/jdk1.8.0_381.jdk/Contents/Home命令行中确认javac与java指向同一 JDKwhich javac which java ls -la $(dirname $(dirname $(which javac)))/jre # 输出应显示 jre 目录存在证明是完整 JDK若javac指向 OpenJDK 而java指向 Oracle JDK需统一环境变量export JAVA_HOME/path/to/jdk1.8.0_381 export PATH$JAVA_HOME/bin:$PATH注意不要尝试手动复制rt.jar或修改ext/目录——这是反模式且 JDK 9 已移除rt.jar。5.4 工资计算结果偏差 0.01 元的调试技巧当calculateTotalSalary()返回值比预期少 0.01大概率是MathContext未全局生效。在SalaryCalculator.java中插入调试日志public BigDecimal calculateTotalSalary(...) { System.out.println(Base: base , Bonus: bonus , Allowance: allowance); BigDecimal sum base.add(bonus).add(allowance); System.out.println(Sum before deduction: sum); BigDecimal result sum.subtract(deduction, MC); System.out.println(Final result: result); return result; }观察输出是否出现9299.149999999999类似值。若存在说明某处BigDecimal构造未用toString()需定位到具体字段如emp.getBonus()返回double并修正为// 错误写法引入浮点误差 new BigDecimal(emp.getBonus()) // 正确写法精确构造 new BigDecimal(Double.toString(emp.getBonus()))本文还有配套的精品资源点击获取
返回列表