Java+Swing+MySQL停车场管理系统:从数据建模到避坑实战

发布时间:2026/10/5 4:02:18

Java+Swing+MySQL停车场管理系统:从数据建模到避坑实战 简介一套基于Java语言、Swing图形框架和MySQL数据库的停车场管理系统主要面向Java初学者、课程设计或毕业设计人群解决车辆出入登记、车位动态分配、用户信息管理及交易记录查询等实际问题。系统采用MVC分层架构通过JDBC完成数据持久化界面层使用Swing构建登录、车位管理、车辆登记等可视化模块同时融入事件监听、线程并发、数据校验、异常处理和SQL注入防护等关键技术并设计了车位表、车辆表、用户表、交易表以主外键关联展示数据库设计方法。压缩包共79个文件包含25个Java源文件、47个class编译文件、1个sql数据库脚本、1个jar依赖库以及工程配置和界面预览图总大小2.08MB结构清晰适合直接导入开发工具阅读和二次开发。目前已有2351人学习下载具备较好的参考价值通过阅读源码可以完整掌握从建表、连接数据库到界面交互、业务逻辑实现的开发链并以此为基础扩展预约计费、月卡会员等更丰富的停车管理功能。1. JavaSwingMysql停车场管理系统从“能跑起来”到“敢交出去”的完整落地方案如果你在搜这个标题大概率是接到了一份课程设计或毕设任务用 Java 写一个带界面的桌面程序配上 MySQL 做数据存储做一个能管理车辆进出、计费、查记录的停车场系统。这个组合看起来老但实际做起来有一堆“看起来很基础、一跑就翻车”的坑Swing 线程卡死、MySQL 连不上、表格刷新后选不中行、计费逻辑在跨天时算错。这篇笔记按我实际做过的一套方案从数据模型到界面代码到避坑经验一步步拆给你看新手照着能做出一个可演示、可答辩、可扩展的完整项目熟手也能在这里面看到参数边界和几个值得注意的细节。2. 先把数据模型定对这决定了你后面是改界面还是改数据库很多人习惯先写界面后建表做到一半发现车位状态、计费时长、会员折扣这些字段没地方放再回头改表结构等于把 UI 层的数据绑定逻辑重写一遍。我一般反着来先定 MySQL 的表结构和 JDBC 连接方式因为 Swing 端的 JTable、JComboBox、JTextField 都是围绕数据模型转的。2.1 三张核心表加一个视图车位表、入场记录表、收费规则表和今日统计视图停车场系统最少要管三类数据车位本身车位号、类型、状态、车辆入场出场记录车牌、入场时间、出场时间、费用、收费规则按时收费还是按次收费会员有没有折扣。我常用的建表 SQL 如下CREATE DATABASE parking_system CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE parking_system; -- 车位表 CREATE TABLE parking_space ( space_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 车位ID, space_no VARCHAR(10) NOT NULL UNIQUE COMMENT 车位编号如A01, space_type TINYINT NOT NULL DEFAULT 0 COMMENT 0-普通车位 1-大型车位 2-充电车位, status TINYINT NOT NULL DEFAULT 0 COMMENT 0-空闲 1-占用, -- 用状态字段而不是删除记录方便统计和使用率 create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB COMMENT车位表; -- 入场记录表 CREATE TABLE parking_record ( record_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 记录ID, plate_no VARCHAR(20) NOT NULL COMMENT 车牌号, space_id INT NOT NULL COMMENT 车位ID, entry_time DATETIME NOT NULL COMMENT 入场时间, exit_time DATETIME DEFAULT NULL COMMENT 出场时间NULL表示还在场内, fee DECIMAL(8,2) DEFAULT 0.00 COMMENT 应收费用, pay_status TINYINT NOT NULL DEFAULT 0 COMMENT 0-未支付 1-已支付, INDEX idx_plate_entry (plate_no, entry_time), INDEX idx_space_status (space_id, exit_time), CONSTRAINT fk_record_space FOREIGN KEY (space_id) REFERENCES parking_space(space_id) ) ENGINEInnoDB COMMENT停车记录表; -- 收费规则表 CREATE TABLE fee_rule ( rule_id INT PRIMARY KEY AUTO_INCREMENT, rule_name VARCHAR(50) NOT NULL COMMENT 规则名称如白天时段、夜间时段, unit_price DECIMAL(6,2) NOT NULL COMMENT 每小时的单价, free_minutes INT NOT NULL DEFAULT 15 COMMENT 免费停车分钟数, daily_cap DECIMAL(8,2) DEFAULT NULL COMMENT 单日最高收费NULL表示不封顶 ) ENGINEInnoDB COMMENT收费规则表;这里我特意用space_id做外键关联而不是直接用space_no字符串关联。原因是车位编号以后可能调整比如 A01 改成 A02如果用字符串关联改编号时所有停车记录都要跟着改用自增 ID 关联编号只是一个显示属性想怎么改都行。pay_status字段是给“先出场后缴费”或“出场时直接结算”两种流程留的后路。课程设计一般做成出场时立刻按规则算费、显示金额、确认收费后出场。但如果导师要求做“预缴费”或“离场后补缴”有这个字段就不会被动。创建视图-- 今日停车统计数据按小时统计车辆进出数量 CREATE VIEW daily_stats AS SELECT HOUR(entry_time) AS hour_of_day, COUNT(*) AS entry_count, SUM(CASE WHEN exit_time IS NOT NULL THEN 1 ELSE 0 END) AS exit_count FROM parking_record WHERE DATE(entry_time) CURDATE() GROUP BY HOUR(entry_time);视图的主要目的是把统计逻辑放在 MySQL 端Swing 界面只需要SELECT * FROM daily_stats就能拿数据填充柱状图或表格。如果你在界面上用 Java 代码去统计不仅代码量大还会因为日期格式处理和时区差异产生一堆边界问题。2.2 JDBC 连接池和时区连接参数这五个参数能帮你少踩 80% 的连接坑MySQL 连接是新手最先翻车的地方。常见的报错是CLIENT_PLUGIN_AUTH is required、Public Key Retrieval is not allowed、The server time zone value is unrecognized。我用的连接参数如下public class DBUtil { // 注意连接池使用 HikariCPJVM 启动时加载配置文件 private static final String URL jdbc:mysql://127.0.0.1:3306/parking_system?useUnicodetruecharacterEncodingutf8mb4useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue; private static final String USER root; private static final String PASSWORD your_password; static { try { Class.forName(com.mysql.cj.jdbc.Driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } }重点说两个参数serverTimezoneAsia/Shanghai解决 MySQL 8.x 默认时区与本地时区不一致导致的日期偏移问题不设置它java.util.Date写入DATETIME字段时可能差 8 小时。allowPublicKeyRetrievaltrue解决 MySQL 8.0 使用caching_sha2_password认证时客户端无法自动获取公钥导致的连接失败。这两个是纯血泪经验每次换新环境必查。注意千万不要用 Statement 拼接 SQL。哪怕停车场系统看起来“没有安全问题”课程设计答辩时老师一定会问 SQL 注入。使用PreparedStatement是底线也算一个答辩加分点。3. Swing 界面分层与实时刷新把 JTable 和车位状态做成联动Swing 写界面难度不高难的是界面和数据的同步。一个停车场管理系统最核心的界面是车位状态总览和车辆出入操作窗口。如果每个窗口用独立的JFrame且不做刷新联动会非常难维护。3.1 主界面用 CardLayout总览、出入管理、记录查询三个面板切来切去我设计的主框架是单窗体 JMenuBarCardLayout。左边功能菜单右边内容面板点击菜单切换卡片如下代码片段public class MainFrame extends JFrame { private CardLayout cardLayout new CardLayout(); private JPanel contentPanel new JPanel(); // 三个主要面板 private SpacePanel spacePanel; private InOutPanel inOutPanel; private RecordPanel recordPanel; public MainFrame() { setTitle(停车场管理系统); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(1100, 700); setLocationRelativeTo(null); // 初始化三个面板 spacePanel new SpacePanel(); inOutPanel new InOutPanel(); recordPanel new RecordPanel(); contentPanel.setLayout(cardLayout); contentPanel.add(spacePanel, space); contentPanel.add(inOutPanel, inout); contentPanel.add(recordPanel, record); // 菜单栏切换 JMenuBar menuBar new JMenuBar(); JMenu menu new JMenu(功能操作); JMenuItem item1 new JMenuItem(车位总览); JMenuItem item2 new JMenuItem(车辆出入); JMenuItem item3 new JMenuItem(记录查询); item1.addActionListener(e - cardLayout.show(contentPanel, space)); item2.addActionListener(e - cardLayout.show(contentPanel, inout)); item3.addActionListener(e - cardLayout.show(contentPanel, record)); setJMenuBar(menuBar); setContentPane(contentPanel); } }CardLayout 的优点是状态隔离三个面板互不干扰切走再切回来不会因为界面重建导致数据丢失。这里注意一点——数据库连接不能放在界面类里而应该通过一个 Service 层传递。界面类只负责展示和接收交互访问数据库的逻辑单独放到SpaceService、RecordService里答辩时老师问“三层架构”时你直接指代码就完事了。3.2 车位状态面板一个 JTable 绑定所有车位用 TableModel 控制颜色和按钮车位总览最常用的展示方式是“网格状车位图”或“JTable 列表”。做一个像高德地图地停车场一样每一格一个车位号的网格用GridLayout 一堆JButton是可以的但后期做“点击车位移到出入窗口”这个联动时需要先拿到按钮的坐标、车位号、状态再切换 card代码会变得很乱。我更喜欢用 JTablepublic class SpacePanel extends JPanel { private JTable table; private SpaceTableModel model; public SpacePanel() { setLayout(new BorderLayout()); model new SpaceTableModel(); table new JTable(model); // 给表格加一个渲染器占用车位显示红色空闲显示绿色 table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() { Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component c super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column); int status (int) model.getValueAt(row, 3); // 第4列是status if (status 1) { c.setBackground(new Color(255, 200, 200)); } else { c.setBackground(new Color(200, 255, 200)); } return c; } }); // 点击某一行联切换到出入管理面板 table.addMouseListener(new MouseAdapter() { Override public void mouseClicked(MouseEvent e) { int row table.getSelectedRow(); if (row ! -1) { String spaceNo model.getValueAt(row, 1).toString(); int status (int) model.getValueAt(row, 3); // 触发自定义事件通过主界面切换 card AppContext.getMainFrame().switchToInOut(spaceNo, status); } } }); add(new JScrollPane(table), BorderLayout.CENTER); } public void refreshData() { model.refresh(); } }这里的SpaceTableModel继承AbstractTableModel数据从SpaceService获取。refreshData()方法在每次“车辆入场”“车辆出场”操作完成后都会被调用。你不用全表重查只需要在INNER JOIN parking_space时加状态判断用一个WHERE status0或status1过滤就能控制列表内容。我把刷新函数设计为 public这样其他面板比如 InOutPanel 执行完入场后可以直接调用spacePanel.refreshData()刷新车位状态不需要设置复杂的事件监听。简单直接课程设计完全够用。4. 车辆出入与计费把“临时车、月租车、会员折扣”一次讲清楚出入操作是停车场系统的业务核心级模块。入口和出口逻辑上有很大不同但计费逻辑是共用的。这一章重点讲计费公式、跨天停车时长计算和几个影响金额的边界情况。4.1 入场登记三个输入框加一个 ComboBox入场时间以数据库当前时间为准入场操作逻辑很直接输入车牌号、选择车位类型如果让用户手动分配车位或车辆自动分配车位、点击“确认入场”。public class InOutPanel extends JPanel { private JTextField plateField new JTextField(12); private JComboBoxString spaceTypeBox new JComboBox(new String[]{普通车位, 大型车位, 充电车位}); private JButton entryButton new JButton(确认入场); private JButton exitButton new JButton(确认出场); public void doEntry() { String plate plateField.getText().trim(); if (plate.isEmpty()) { JOptionPane.showMessageDialog(this, 请先输入车牌号); return; } // 调用 Service 层找到空闲车位并更新状态 boolean success RecordService.getInstance().entryParking(plate, (String) spaceTypeBox.getSelectedItem()); if (success) { JOptionPane.showMessageDialog(this, 入场成功); plateField.setText(); AppContext.getMainFrame().refreshAllDatas(); } else { JOptionPane.showMessageDialog(this, 没有可用车位或该车牌已在场内, 错误, JOptionPane.ERROR_MESSAGE); } } }这里有个小坑车牌号应该统一转大写并去空格。用户输入“京a12345”和“京A12345”在数据库中会被当成两辆车。我做法是plate plate.toUpperCase().replace( , )同时数据库字段排序规则用utf8mb4_unicode_ci大小写不敏感双保险。入场时除了 INSERT 记录还要 UPDATE 车位状态。两个操作必须在一个事务里完成public boolean entryParking(String plateNo, String spaceType) { Connection conn null; try { conn DBUtil.getConnection(); conn.setAutoCommit(false); // 开启事务 // 1. 查询空闲车位 PreparedStatement ps1 conn.prepareStatement( SELECT space_id FROM parking_space WHERE space_type ? AND status 0 LIMIT 1); ps1.setString(1, spaceType); // ... 如果没查到回滚并返回 false // 2. 插入停车记录 PreparedStatement ps2 conn.prepareStatement( INSERT INTO parking_record (plate_no, space_id, entry_time, pay_status) VALUES (?, ?, NOW(), 0)); // 3. 更新车位状态 PreparedStatement ps3 conn.prepareStatement( UPDATE parking_space SET status 1 WHERE space_id ?); conn.commit(); return true; } catch (Exception e) { if (conn ! null) conn.rollback(); e.printStackTrace(); return false; } finally { // 恢复自动提交 } }这里必须用事务否则容易出现“记录插入成功但车位状态没改”或“车位状态改了但记录没插上”的脏数据。这是很多停车场项目运行时出现车满但界面上显示有空位的直接原因。4.2 出场结算与跨天计费为什么你算的钱比系统多两块出场时的核心逻辑是根据车牌找到正在场内未支付的记录计算exit_time - entry_time的小时数按收费规则算出金额更新记录和车位状态。public BigDecimal calcFee(LocalDateTime entryTime, LocalDateTime exitTime) { // 使用 Duration 计算分钟差避免 Java 8 之前 Date 计算的繁琐 Duration duration Duration.between(entryTime, exitTime); long minutes duration.toMinutes(); // 免费 15 分钟 long billableMinutes minutes - freeMinutes; if (billableMinutes 0) { return BigDecimal.ZERO; } // 按小时向上取整收费 long hours (billableMinutes 59) / 60; BigDecimal fee new BigDecimal(hours).multiply(unitPrice); // 单日封顶逻辑 if (dailyCap ! null duration.toHours() 24) { if (fee.compareTo(dailyCap) 0) { fee dailyCap; } } return fee; }跨天计费是最容易出错的点。假设入场时间是昨天 23:50出场是今天 01:10总时长只有 1 小时 20 分钟。但如果按“日期”而不是“时间差”去算比如用(exitDate - entryDate) * 24再减掉头尾就会得出一个奇怪的负数或者多收两倍费用。正确做法是统一用LocalDateTime做差不要让“跨天”这个概念进入到计算逻辑里时间差就是时间差跟日期无关。另一个新手常犯的问题是浮点精度用double计算 0.1 * 3 会得到 0.30000000000000004存到 DECIMAL 字段时数据库会警告或报错。所以费用计算必须用BigDecimal且金额字段全部用DECIMAL(8,2)。4.3 计费规则的可配置化不是每个停车场都是 5 元/小时如果你把收费标准写死在 Java 代码里导师大概率会问“如果停车场调价了怎么办”。所以我把fee_rule表做成可配置的字段含义推荐值unit_price每小时单价5.00 元/小时free_minutes免费时长15 分钟内免费daily_cap每日封顶30 元/天界面上做一个“收费规则维护”窗口用 JTable 展示fee_rule表双击单元格即可修改单价保存时 UPDATE。这样演示时展示调价后新入场车辆的费用变化比写死参数的效果好很多。一个容易忽略的细节调价只影响新生成的计费已在场的车辆应该按入场时的规则计费还是按出场时的最新规则计费我建议按出场时的规则简单好解释如果你要按入场时规则需要在parking_record表加一个rule_id字段保存入场那一刻的规则快照。这就是数据模型设计时留下的灵活性。5. Swing 线程与数据库操作避坑界面卡死、表格不刷新、车位状态错乱的五个真实案例做 Swing 桌面程序最头疼的不是功能实现而是“界面为什么卡住不动”和“数据为什么跟数据库对不上”。这一章把我反复踩过的坑集中列出来每一条都是现象到原因的完整链路。5.1 卡死在主线程上耗时数据库操作阻塞了 UI 绘制现象点击“查询”后整个窗口变成白色鼠标转圈过两三秒才恢复。如果数据量大甚至变成“未响应”状态。原因Swing 的事件分发线程EDTEvent Dispatch Thread负责所有界面绘制和事件响应。如果你在按钮的addActionListener里直接执行 JDBC 查询数据库查询耗时期间 EDT 被占住界面就没有机会重绘。解决用SwingWorker把耗时操作放到后台线程SwingWorkerListRecordVO, Void worker new SwingWorker() { Override protected ListRecordVO doInBackground() { // doInBackground 在后台线程执行不卡界面 return RecordService.getInstance().queryRecords(startTime, endTime, plateNo); } Override protected void done() { // done 在 EDT 线程执行可以安全更新界面 try { ListRecordVO data get(); recordTableModel.setData(data); } catch (Exception e) { JOptionPane.showMessageDialog(RecordPanel.this, 查询失败: e.getMessage()); } } }; worker.execute();这里有一个小细节done()方法里不能再访问数据库因为它在 EDT 执行需要数据就在doInBackground()里准备好done()只拿现成结果刷新 JTable。5.2 表格刷新后选不中行你更新了 model 但忘了通知 JTable现象执行“车辆出场”后调用了model.refresh()获取新列表Interface 上表格数据变了但点击某一行时getSelectedRow()偶尔返回 -1或者选中的是旧数据的索引。原因刷新数据时如果直接清空Vector里的元素而不调用fireTableDataChanged()JTable 的视图缓存还是旧的。更隐蔽的是如果getSelectedRow()在鼠标事件里读取而 model 数据刚刷新完成行索引已经变化但选择模型还没更新。解决在SpaceTableModel.refresh()方法末尾强制调用fireTableDataChanged()在刷新完成后调用table.clearSelection()清掉旧选择再重新设置默认选中第一行。这样界面状态是干净的不会出现“点哪一行都没反应过一会儿又好了”的玄学 bug。5.3 同一辆车重复入场缺少唯一性约束现象系统允许同一车牌连续点击两次“确认入场”生成两条入场记录占两个车位。原因入场逻辑只查了“这个车牌有没有在场内未出场的记录”但没加数据库级约束并发点击时两个请求都通过了检查。解决除了在 Java 代码中查询exit_time IS NULL的记录更保险的是给数据库加一个条件性唯一索引MySQL 8.0 支持函数索引CREATE UNIQUE INDEX uk_active_plate ON parking_record ((CASE WHEN exit_time IS NULL THEN plate_no END));这种只在未有exit_time的记录上唯一约束已经出场的车牌可以重复入场。同时更新入场代码// 在事务里查询是否存在未出场记录 SELECT COUNT(*) FROM parking_record WHERE plate_no ? AND exit_time IS NULL FOR UPDATE;FOR UPDATE加上行锁防止两个事务同时查出“不存在”然后都插入成功。这算是进阶一点的做法但能直接在答辩时体现“并发控制”意识。5.4 MySQL 8.x 连接报错的一键排查顺序现象项目在别人电脑上跑得好好的到我这就报Communications link failure或Access denied for user。原因环境不同导致的连接参数不匹配。常见情况有三种MySQL 服务没启、密码不对、连接 URL 里的时区或 SSL 参数不匹配。解决按顺序排查。第一步ping 127.0.0.1看网络通不通第二步telnet 127.0.0.1 3306看端口通不通第三步用mysql -uroot -p直接命令行连接看是否能登录。前三步过了再去检查driver版本和URL参数。MySQL 5.7 之前的驱动类名是com.mysql.jdbc.Driver8.x 之后是com.mysql.cj.jdbc.Driver用错必报ClassNotFoundException或No suitable driver found。5.5 中文乱码问题终端和数据库双向都要对齐现象界面上车牌显示正常但存到数据库变成 “????”或者数据库中中文正常界面读出变成乱码。原因MySQL 连接 URL 里没加characterEncodingutf8或者数据库表建立时没用utf8mb4字符集。Swing 默认字体在有中文时如果不是中文字体也可能显示方块。解决统一三个层级的字符集。MySQL 建库时用CHARACTER SET utf8mb4注意不是utf8utf8mb4 才是真正的四字节全量中文支持连接 URL 加useUnicodetruecharacterEncodingutf8mb4JVM 启动参数加-Dfile.encodingUTF-8。Swing 字体设置可以用“UIManager.put(Label.font, new Font(Microsoft YaHei, Font.PLAIN, 14))”。这一套做好之后中文乱码基本绝迹。6. 验证、演示与扩展方向把项目从“交差”做到“有亮点”项目功能写完只是第一步你需要花时间在验证和演示环境上。很多人在答辩现场翻车不是代码写得不对而是演示路径没设计好现场排队等入场时数据库状态错乱表格刷新不及时给人印象分很差。6.1 最小演示脚本五步走完整个业务闭环我建议你准备一份“演示剧本”保证五分钟之内把系统完整讲清楚启动 MySQL 服务和项目打开“车位总览”显示所有车位为绿色空闲状态。录入一辆临时车“京A12345”入场界面刷新后对应车位变红色车位数量减一。等待一分钟或手动修改entry_time为两小时前用 SQL UPDATE 语句为了触发大于免费时长的计费然后点击“确认出场”弹窗显示收费金额。打开“记录查询”按车牌检索刚才的出入场记录展示费用状态“已支付”。最后展示“收费规则维护”窗口把单价从 5 元改为 8 元再演示一次入场说明调价对后续车辆生效。这五步覆盖了系统的核心模块也展示了数据库写入、事务、价格可配置这几个加分点。不需要演示会员卡充值、月租车续费等扩展功能除非你确定那部分代码稳定。6.2 用 SQL 直接制造测试数据避免现场等一小时开发调试时如果每次都等真实时间经过才有费用计算效率太低。我在开发过程中经常直接手动 UPDATE 入场时间-- 把指定记录的入场时间改为 3 小时前用于测试计费逻辑 UPDATE parking_record SET entry_time DATE_SUB(NOW(), INTERVAL 3 HOUR) WHERE record_id 1;注意操作后退出重新查询或点击“刷新”确保界面拿到的数据是新的。这种做法我常称为“后悔药”——因为如果你写了一个entryButton的模拟等待线程很容易把自己绕晕。6.3 扩展方向加一个“可视化统计”和“导出报表”课程设计如果要拿高分最好加一个“今日车流量”折线图和“导出 Excel”功能。前者用 JFreeChart 库读取daily_stats视图画一个 24 小时入场台数柱状图。后者用 Apache POI 把parking_record表的数据写入.xlsx文件// 导出停车记录到 Excel try (Workbook workbook new XSSFWorkbook()) { Sheet sheet workbook.createSheet(停车记录); Row header sheet.createRow(0); header.createCell(0).setCellValue(车牌号); header.createCell(1).setCellValue(入场时间); header.createCell(2).setCellValue(出场时间); header.createCell(3).setCellValue(费用); // ... 遍历数据填充行 try (FileOutputStream fos new FileOutputStream(parking_records.xlsx)) { workbook.write(fos); } }POI 导出的一个常见坑是“行数多时内存占用高”但对于停车场这种日记录量最多几千条的系统完全不用担心。如果你要导出的是月报表十万条级别改一下 POI 的流式写入模式即可。6.4 我对课堂项目最后的一点点建议做完以上内容你的 JavaSwingMysql 停车场管理系统已经从“能跑”进化成“能讲清楚、能演示闭环、能在答辩现场顶住追问”的状态。数据模型上有唯一索引和事务界面代码有 SwingWorker 防卡顿计费逻辑有 BigDecimal 和跨天处理扩展功能有统计报表和导出文件。亲自踩一遍以上这些坑是很值得的——我当年就是因为没处理 SwingWorker在导师面前演示查询时界面卡了五秒那句“为什么这么慢”一问出来我就知道这个项目还没做完。后来把线程问题、事务问题按要求改一遍思路顺畅很多。希望这篇笔记对你有所帮助也祝你一次通过。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/5 4:02:18

基于Springboot的一站式家装服务管理系统毕设全解析

每年三四月,学Java的同学基本都躲不开一个问题:Springboot的毕业设计选题怎么定。选图书管理这类经典题目,怕答辩时没东西讲;选电商商城,又怕业务太复杂做不完。我近几年带过的毕设项目里,基于Springboot的…

2026/10/5 3:57:18

插件加载失败排查指南:从IAR、web boot到MusicFree的通用方法

plugins这个词,说大不大,说小不小。最近好几个热词都在围着它转——既有嵌入式开发老手在搜“IAR plugins是干什么的”,也有前后端工程师对着failed to load plugins web boot: 2 entries did not activate这种报错挠头,还有不少人…

2026/10/5 3:57:18

海康威视摄像头接入OpenCV人体识别:RTSP取流与模型选型实战

简介:这套项目面向计算机视觉方向的毕业设计或课程设计,围绕海康威视网络摄像头实时视频流,完整实现基于OpenCV的HOGSVM人体识别与检测流程。压缩包整理为可直接运行的VS工程,包含主程序、摄像头采集模块、YV12转RGB处理、人体检测…

2026/10/5 4:47:20

UE5地编法线贴图DirectX与OpenGL坐标系差异及转换指南

地编入门第一课,往往不是刷地形,也不是摆资产,而是先把法线贴图的坐标系搞清楚。很多人在 UE5 里导入一张法线贴图,发现光照方向不对、墙面凸起变凹陷、地面材质看起来发灰发闷,排查到最后,经常就是 Direct…

2026/10/5 4:47:20

从零手搓本地知识库问答机器人:LangChain+FAISS+本地模型实战

1. 为什么我要从零手搓一个个人知识库问答机器人先说结论:我折腾这个项目的出发点特别朴素——我的笔记和文档散落在四五个地方,Obsidian 里一堆 Markdown、本地存了几百个 PDF、浏览器书签里还躺着一堆技术博客,每次想找点东西都得靠grep加肉…

2026/10/5 4:47:20

数据结构栈

1. 栈的基本概念 1.1.1 概念 栈(Stack)是一种限定仅在表的一端进行插入和删除操作的线性表。这一端称为栈顶(top),另一端称为栈底(bottom)。当栈中不包含任何元素时,称为空栈。 栈遵…

2026/10/5 4:42:20

STM32 LwIP网线插拔自动恢复:轮询与中断方案详解

说实话,这标题我太有共鸣了。搞过 STM32 联网项目的工程师基本都栽过同一个跟头:板子刚开始调通 LwIP 的时候,网线插上 ping 得通,拔了再插,十几秒后怎么 ping 都没反应。接着就是关电源重上电,网络又活了。…

2026/10/4 0:01:02

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

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

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑