
简介这是一份基于 GUI/Swing 与 MySQL 的商品库存管理系统 Java 课程设计资源适合需要完成相关课设、快速入门桌面应用开发的学生使用。压缩包共 52 个文件、约 351KB包含可直接导入运行的 Java 源码、编译后的 class 文件、数据库脚本 commodity.sql、课设报告 docx以及登录账号密码说明结构上按 src、out、img 等目录组织方便阅读与提交。系统界面保持原始朴素风格功能围绕商品与库存管理展开满足常见课设要求可直接运行演示或基于源码二次修改。目前已有 449 人浏览学习对急需交付课设或复习 Swing/JDBC 编程具有一定的参考价值。资源来自实际接单项目经过顾客运行验证能够正常启动适合作为过审课设的稳妥方案。1. 商品库存管理系统Java 课设最稳的 Swing MySQL 组合如果你正在为 Java 课程设计发愁这个商品库存管理系统值得认真看一遍。它用的是经典的 GUI/Swing 桌面端加 MySQL 数据库不是花哨的 Web 项目技术栈完全对应课设大纲里最常出现的几个点Swing 界面、JDBC 连接、SQL 脚本和数据展示。资源里带完整的源代码、数据库脚本 commodity.sql 和课设报告环境配好就能直接跑。适合手里没有完整可运行源码、又想让老师现场点开就能演示的同学。不用刻意美化界面能稳定运行、能讲清每个类的作用往往才是通过课设的关键。2. 跑通课设的第一关环境选型与项目结构2.1 为什么是 Swing MySQL课设评审最关心的技术点Java 课设选 Swing很多人觉得老但它其实是风险最低的方案。Swing 从 JDK 1.2 开始就是标准库的一部分不需要额外装 JavaFX SDK也不需要配置复杂的模块化参数。老师课堂上讲过的组件基本都能直接套用JFrame 做窗体、JTable 做列表、JTextField 做输入框、JButton 做按钮这些组件拼起来就是一套完整的库存管理界面。相比之下JavaFX 虽然界面更现代但很多学校的实验环境里并没有装对应插件课设答辩现场出问题的几率高不少。MySQL 这边也一样它是最容易装、学习资料最多的关系型数据库。课设里用 MySQL 存商品信息和登录账号能直接体现 JDBC 编程能力。如果贪图简单用文本文件或对象序列化存数据代码量是少了但讲不出“数据表设计”和“SQL 查询”这两个课设必考点分数很容易被压下去。反观 MySQL 8.0安装包里自带可视化配置向导驱动选 mysql-connector-java 8.0.x整个链路是通的。这套系统是 C/S 架构也就是客户端加服务器。Swing 写客户端MySQL 当服务器两者通过 JDBC 通信。很多同学会担心老师会不会觉得桌面端不如 Web 端高级我的看法是课设题目只写了“商品库存管理系统”没限定必须用浏览器访问。桌面程序有自己的优势比如双击就能运行、不需要启动 Tomcat、不占端口演示的时候最少受外部环境影响。对答辩来说稳定运行比技术栈新更重要。还有一个容易被忽略的点这份项目是纯 Java 工程没有引入 Maven 或 Gradle没有 SSH 框架连配置文件都很少。这意味着你用 IDEA 直接打开源码目录指定好 JDK再导一个 MySQL 驱动 jar 就能跑。对那些还在补 Java 基础、连 Maven 依赖都还没搞明白的同学这种项目反而更友好。它让你把注意力放在 Swing 事件和 JDBC 语句上而不是跟一堆 XML 配置搏斗。2.2 拿到压缩包后的标准导入流程从解压到跑起来的四步我按自己平时复核课设项目的顺序给你一套标准导入流程。第 1 步把压缩包解压到一个没有中文和空格的路径下比如 D:/inventory。这个细节非常重要路径里只要出现中文空格后面配置 classpath 或者数据库 URL 都可能出现玄学问题报错又怪不到路径上排查起来非常费时。第 2 步确认 MySQL 服务已经启动。如果你装的是 MySQL 8.0Windows 上通常会出现一个名为 mysql80 的系统服务。用管理员身份打开命令行执行下面两条命令去确认net start mysql80 mysql -uroot -p第一条命令是启动 MySQL 服务如果服务本来就开着会提示“请求的服务已经启动”。第二条是登录 MySQL输入安装时设置的 root 密码。这一步的意义在于先确认数据库真的能连上再把锅甩给 Java 代码。很多同学报“连接失败”其实根本不是代码问题而是服务没启动。服务名不一定叫 mysql80有的版本叫 MySQL80也有自定义的不确定时用 sc query 查看sc query | findstr /i mysql看到服务名之后用对应的名字启动即可。第 3 步用 IDEA 打开项目。打开时直接选择解压后的根目录IDEA 会根据里面的 .iml 文件和 src 目录识别出这是一个 Java 项目。打开后先做一件事进入 File - Project Structure把 Project SDK 选成本机安装的 JDK通常选 1.8 或 11 都可以。如果代码里有用到新语法再考虑更高版本。确认无误后把 MySQL 驱动 jar 放到 lib 目录下或者通过 Project Structure 里的 Libraries 手动添加。第 4 步是导入数据库脚本。资源里的 commodity.sql 建好了库存系统需要的表和初始数据。导入方式多种多样我最推荐命令行因为错误信息最直观。假设你已经创建好了一个名为 inventory 的数据库导入命令如下mysql -uroot -p inventory D:/inventory/commodity.sql没有提前建库的话先登录 MySQL执行建库再导入。注意字符集一定要显式指定 utf8mb4CREATE DATABASE inventory DEFAULT CHARACTER SET utf8mb4; USE inventory; SOURCE D:/inventory/commodity.sql;这段 SQL 先建数据库再切换到目标库最后用 SOURCE 命令执行脚本。为什么用 utf8mb4 而不是 utf8因为 utf8mb4 是 utf8 的超集能正确存储中文、表情符号和一些特殊字符。很多老项目中文乱码就是因为建库时默认用了 latin1字段再怎么写 utf8 都没用。导入完成后执行一个查询看看数据是否真的进去了SELECT id, name, stock FROM goods LIMIT 5;如果能返回商品记录说明表结构和初始化数据都正常。如果返回 Empty set先别急着改 Java 代码回头查两件事导入时是否切换到正确的数据库SQL 文件里是否带了 USE 语句把库切走了。很多同学在 Navicat 里导入成功结果打开 Java 程序依然报“表不存在”多半就是脚本执行到了别的库。到这里环境准备就做完了。我建议你在这一步多花十分钟做一件事把源码里的数据库连接串打开看一眼确认库名、用户名、密码和本机配置一致。不要急着运行先看再跑能省掉后面一半的报错。3. 数据库脚本 commodity.sql库存表结构与登录数据3.1 先看表结构商品、库存、登录三张表的关联拿到 commodity.sql第一件事不是双击运行而是先打开看表结构。很多同学把导入脚本当成“一键完成”的黑匣子全自动灌入之后就再也不管了直到答辩时被老师问“你这几张表怎么关联的”才支支吾吾。为了避免这种尴尬建议你从脚本里提取出核心表理解每一张表存在的理由。按这类课设的常见设计里面至少会有三张关键表用户表 user、商品表 goods、库存流水表 stock_log。用户表管登录商品表存商品名称、价格、库存数量库存流水表记录每次入库出库的明细。三张表通过外键关联起来商品表的主键 id 被库存流水表的 goods_id 引用。典型的建表语句长这样CREATE TABLE user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(30) NOT NULL UNIQUE, password VARCHAR(50) NOT NULL ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE goods ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, spec VARCHAR(50), price DECIMAL(10,2), stock INT DEFAULT 0, min_stock INT DEFAULT 10 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE stock_log ( id INT PRIMARY KEY AUTO_INCREMENT, goods_id INT, change_count INT, log_time DATETIME, FOREIGN KEY (goods_id) REFERENCES goods(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;我把表结构拆开说明一下。user 表里 username 设置了 UNIQUE 约束这是为了防止同一账号重复注册也方便登录时精确匹配。password 字段用的是 VARCHAR(50)课设阶段明文存储就够了不需要刻意去做加密。goods 表里 price 用 DECIMAL(10,2) 而不是 DOUBLE是因为浮点数在运算时会产生精度误差比如 0.1 加 0.2 不等于 0.3DECIMAL 可以直接避免这个坑。stock 字段保存当前库存数量min_stock 字段是给“最低库存预警”预留的这个字段在后面的进阶功能里会很有用。stock_log 表是典型的流水表每一条记录表示一次库存变动。change_count 正数表示入库负数表示出库log_time 记录操作时间。通过 goods_id 外键和 goods 表关联查询时把两张表 JOIN 起来就能得到“某商品最近这段时间的出入库情况”。答辩时如果老师问“库存变动你怎么追踪”你指一下这张表就行。为什么强调用 InnoDB 引擎InnoDB 支持外键和事务MyISAM 更老但两者都不支持事务。课设里的“入库出库”操作往往要同时更新 goods 表的 stock 字段和 stock_log 表没有事务的话两步操作之间只要一步失败数据就对不上。如果你在答辩时主动提一句“我用 InnoDB 是为了保证事务一致性”会比单纯描述功能更扎实。当然实际下载到的脚本不一定跟我上面写的一模一样字段名可能叫 product 而不是 goods也可能没有 stock_log 表。但核心思路一致用户账号、商品信息、库存记录三者凑齐就是一个完整的库存管理系统。你花半小时把脚本里的表名和字段名记在纸上后面看 Java 代码会轻松很多。3.2 导入脚本与初始化数据导入脚本的具体命令在第 2 章已经给过这里重点说导入之后怎么验证以及常见的坑。数据导入完成第一件事是查用户表SELECT * FROM user;正常情况下会看到一条 admin 账号记录密码有可能也是 admin。这个账号就是资源说明里提到的“登录的账号密码”。如果查询结果为空说明脚本在导入时跳过了这条 INSERT或者建表成功但没有插入初始数据。这时候手动补一条INSERT INTO user (username, password) VALUES (admin, admin);插入后再次查询确认记录存在。注意如果 Java 代码里的连接库名不是 inventory而是别的名字你需要把表和插入语句全部迁移过去最稳妥的办法是修改 Java 代码里的连接串让代码指向你实际导入数据的库。初始化数据验证完后再检查一下商品表和流水表的关系是否正常。执行一条多表关联查询SELECT g.name, s.change_count, s.log_time FROM stock_log s LEFT JOIN goods g ON s.goods_id g.id ORDER BY s.log_time DESC LIMIT 10;这条 SQL 的作用是把 stock_log 表和 goods 表关联起来按时间倒序看最近 10 条库存流水。如果查询报“Unknown column”错误说明字段名对不上去核对 sql 脚本里两张表的实际字段名以实际为准。LEFT JOIN 在这里保证即使某条流水对应的商品被删了也能显示流水记录只是商品名称会变成 NULL这样查出来的记录始终不会减少。如果你习惯用 Navicat 这种图形化客户端也有需要注意的地方。右键点击数据库名选择“运行 SQL 文件”再选中 commodity.sql。在点“开始”之前注意看窗口上的“当前数据库”是不是你要导入的目标库。有些版本的 Navicat 会在脚本里没有 USE 语句时把表建在当前选中的数据库上。如果导完之后发现表出现在别的库不要慌重新选对库再导一次即可。还有一种常见报错是导入时提示语法错误但脚本在别人机器上明明没问题。这八成是编码问题。SQL 文件可能是 GBK 编码而你的 MySQL 命令行默认按 UTF-8 解释中文字符串就变成了乱码MySQL 不认识乱码里的引号自然报语法错误。解决办法是在导入命令前面显式指定字符集mysql -uroot -p --default-character-setutf8mb4 inventory commodity.sql如果指定之后还是报错就把 commit.sql 用文本编辑器另存为 UTF-8 格式再执行一次。这个编码坑几乎每个课设季都会出现我一般拿到任何 sql 脚本都会先做一步把文件打开去看中文注释是否显示正常。显示的是乱码先另存再导入不然后面全是冤枉路。导入成功后建议你顺手做一次“SQL 和 Java 代码的字段名核对”。打开项目源码搜索 SELECT 语句把 Java 里用到的表名和字段名与脚本里的建表语句逐一比对。比如 Java 代码里写的是 SELECT * FROM goods但脚本里表名是 product那登录成功后商品列表必然报错。这种问题不在环境配置单纯是版本迭代留下的坑提前核对能省掉答辩前的慌乱。4. 登录模块与主界面账号密码从哪里来4.1 登录校验逻辑与界面事件登录模块是课设答辩时老师几乎必看的部分因为它涵盖了 Swing 事件处理和 JDBC 两条主线。界面本身不复杂两个 JLabel、一个 JTextField、一个 JTextField 或 JPasswordField、一个登录按钮。按钮注册 ActionListener点击后触发 actionPerformed 方法在这个方法里取界面输入再去数据库验证。我把核心代码简化如下btnLogin.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { String username txtUsername.getText().trim(); String password new String(txtPassword.getPassword()); try { Connection conn DriverManager.getConnection( jdbc:mysql://localhost:3306/inventory?useSSLfalseserverTimezoneAsia/Shanghai, root, 123456); PreparedStatement ps conn.prepareStatement( SELECT * FROM user WHERE username? AND password?); ps.setString(1, username); ps.setString(2, password); ResultSet rs ps.executeQuery(); if (rs.next()) { JOptionPane.showMessageDialog(loginFrame, 登录成功); new MainFrame().setVisible(true); loginFrame.dispose(); } else { JOptionPane.showMessageDialog(loginFrame, 用户名或密码错误); } rs.close(); ps.close(); conn.close(); } catch (SQLException ex) { ex.printStackTrace(); } } });先说逻辑。txtUsername.getText().trim() 会去掉用户名首尾空格防止手滑多按一个空格导致匹配失败。new String(txtPassword.getPassword()) 是为了拿到密码框里的真实内容JPasswordField 的 getPassword 返回的是 char 数组直接 toString 拿不到明文。这里用 PreparedStatement 做参数化查询比字符串拼接 SQL 安全得多能避免 SQL 注入。课设阶段虽然不太会真的被攻击但老师问到“为什么不用 Statement”时你能答出“预防拼接注入”印象分会明显不一样。再看连接串参数。localhost 表示本机地址3306 是 MySQL 默认端口inventory 是数据库名必须和实际库名完全一致。useSSLfalse 是关掉 SSL 握手的警告serverTimezoneAsia/Shanghai 是给 MySQL 8.x 指定时区这两个参数不写控制台会刷一堆警告虽然不影响运行但答辩时显得不干净。root 和 123456 是你本机 MySQL 的用户名和密码记得替换成自己的。有一点要提醒很多课设项目的连接串不是写在登录按钮里而是单独抽了一个 DBHelper 类。如果你看到代码里有 DBHelper.getConnection() 这样的调用那连接串大概率集中在这个类里后面改密码会方便很多。登录成功后 new MainFrame().setVisible(true) 打开主界面loginFrame.dispose() 销毁登录窗口这一步目的是避免关掉主界面后登录窗口还在后台占着内存。4.2 修改默认账号密码与重连数据库资源里提到的“登录的账号密码”一般会写在课设报告或者脚本注释里。常见的初始值是 admin / admin。如果你运行之后能直接登录那说明脚本里的数据和代码里的连接串是匹配的。如果登录失败不要一上来就怀疑代码先分两步排查。第一步确认数据库里的账号密码对不对。登录 MySQL查询 user 表SELECT * FROM user;看到记录后检查 username 和 password 是否与你输入的一致。如果想改成自定义密码直接用 UPDATE 语句UPDATE user SET password2024newpass WHERE usernameadmin;执行完这条再重新运行程序用新密码登录。注意如果 Java 代码里对密码做了 MD5 或 SHA 加密那么直接 UPDATE 明文是没有用的代码会把输入加密后再去比对你必须把数据库里的值改成加密后的结果。判断代码有没有加密搜索一下源码里有没有 MessageDigest 或者 DigestUtils 之类的关键词即可。第二步确认 Java 代码里的连接参数。打开 DBHelper 类你会看到类似下面的代码public class DBHelper { private static final String URL jdbc:mysql://localhost:3306/inventory?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8; private static final String USER root; private static final String PASSWORD 123456; public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } }把 USER 和 PASSWORD 改成你本机 MySQL 的实际账号密码。尽量把连接参数集中在一个类里这是课设代码应该有的习惯。如果项目里把连接串写在了每个界面类中登录页面一份、商品管理一份、入库出库一份那改起来非常容易漏。漏掉的后果通常是登录成功了但主界面加载数据时报错或者某个窗口能打开但列表是空的。另外资源里可能已经打包好了 mysql-connector-java 的 jar也可能需要你自己下载。不管哪种都要确保这个 jar 在 IDEA 的 Project Structure - Libraries 里存在。如果你在命令行里运行还要让 classpath 包含这个 jar。这一点经常被忽略导致在 IDEA 里跑得好好的一换到命令行就 ClassNotFoundException。如果你在导入脚本时用了自己创建的数据库名比如叫 stock_db而不是 inventory那就要把上面 URL 路径里的 inventory 改成 stock_db。数据库名不一致的报错很典型登录时始终提示“用户名或密码错误”因为 SQL 里的 user 表根本不在当前库里。这时候控制台通常会打印 Unknown database 或者 Table doesnt exist仔细看堆栈信息就能定位。5. 避坑/常见问题课设跑不通的五个真实翻车点5.1 现象MySQL 连接报 Communications link failure报错长这样Communications link failureThe last packet sent successfully to the server was 0 milliseconds ago. 看到这个第一反应不是代码问题而是连不上 MySQL 服务。原因通常有三个MySQL 服务没启动、端口被占用、URL 里的 host 不对。解决时按顺序排查。先看服务是否启动Windows 下用命令net start mysql80如果提示服务无法启动打开 Windows 服务管理器找到 MySQL 相关服务右键查看依赖项有没有都启动。然后测试端口通不通telnet 127.0.0.1 3306如果你机器上没开 telnet也可以把 URL 里的 localhost 改成 127.0.0.1 试试有些极端情况下 localhost 被解析成 IPv6 的 ::1MySQL 没监听 IPv6 就会失败。如果端口通继续看 URL 里的端口号是不是 3306有没有不小心把端口写成 3307。最常见的翻车场景是装了 XAMPP 或者 phpStudyMySQL 端口被改成了 3307而代码里还写着 3306。还有检查一下防火墙虽然本机访问一般不涉及但有些安全软件会拦截 Java 进程的对外连接。我处理过一例代码和数据库全都没问题最后发现是系统防火墙把 mysql.exe 禁用了导致外部连接全部超时。这个概率不高但阻塞很久才排查到。5.2 现象ClassNotFoundException: com.mysql.jdbc.Driver这个异常的意思是 MySQL 驱动类加载不到。原因有两个方向一是驱动 jar 确实没有加入到项目依赖二是驱动类名写错了。老版本 MySQL 驱动的类名是 com.mysql.jdbc.Driver从 MySQL Connector/J 8.x 开始官方推荐用 com.mysql.cj.jdbc.Driver。资源代码如果是从旧教程抄的用到新驱动时就会找不到类。解决驱动类名找不到最直接的做法是看看你的 jar 包版本。如果使用的是 mysql-connector-java-8.0.x把代码里所有 Class.forName(com.mysql.jdbc.Driver) 改成 Class.forName(com.mysql.cj.jdbc.Driver)。如果懒得改代码也可以去找 5.1.x 版本的旧驱动但我不推荐因为 MySQL 8.0 的默认认证插件是 caching_sha2_password旧驱动不支持即使类加载成功登录时也会报认证错误。相比改类名把立桩码里的驱动类名统一改成新版再同步引入对应版本的 jar是最稳的路径。IDEA 里添加 jar 的操作是File - Project Structure - Libraries - 加号 - Java选择你的 mysql-connector-java jar 文件。加完之后确认它出现在 Modules 的 Dependencies 里而且没有被排除掉。有些同学把 jar 手动拷贝进 src 文件夹里以为这样就“导入”了其实 IDEt 不会自动把 src 下的 jar 加入编译指针必须在 Project Structure 里显式添加才生效。5.3 现象登录界面输入中文后变成问号或乱码中文乱码是课设项目最常见的表现具体是数据库里存进去的中文变成“?”或者在界面上显示成了乱码。原因通常出现在三个层面数据库字符集、JDBC 连接串字符集、IDE 的源码文件编码。第一步检查数据库和表是否用了 utf8mb4。你可以在 MySQL 里执行SHOW CREATE TABLE goods;建表语句里如果没有 DEFAULT CHARSETutf8mb4说明建库时没指定字符集。处理办法是重新创建库或者用 ALTER TABLE 转换ALTER TABLE goods CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;第二步检查连接串有没有加 characterEncoding 参数jdbc:mysql://localhost:3306/inventory?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8这个参数告诉 MySQL 客户端按 UTF-8 编码发送和接收数据。如果少了它连接默认会用服务器端字符集一旦服务器是 latin1中文传输过程就丢失了。第三步也是最容易被忽略的IDEA 的文件编码。进入 File - Settings - Editor - File Encodings把 Global Encoding、Project Encoding、Properties Files 全部设为 UTF-8。很多同学的代码文件本身是 GBK 编码存盘的IDEA 用 UTF-8 打开以后源码里所有中文字符串常量都是乱码这种乱码和数据库没有任何关系。看清文件的右下角如果显示的是 GBK就转换成 UTF-8 再重新编译。5.4 现象运行主类后窗口一闪而过直接退出有些同学喜欢直接双击运行生成的 jar 包结果窗口一闪就没了。这个现象本质是 JVM 在执行主线程时抛出了未捕获异常程序直接终止。常见原因有两个数据库连接失败或者主方法里写了 System.exit() 但前面的初始化代码没有兜底。解决的第一步别用双击运行先回到 IDEA 里点绿色运行按钮。IDEA 的控制台会保留堆栈信息你一眼就能看出异常抛在哪个环节。如果是 SQLException按 5.1 和 5.2 排查。如果是 FileNotFoundException看看代码里读的文件路径是不是写死了绝对路径比如 D://temp/data.txt一旦目录不存在就会崩。还有一个更隐蔽的原因代码里的静态代码块加载驱动失败。比如static { try { Class.forName(com.mysql.cj.jdbc.Driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } }如果驱动 jar 没加到依赖里这里的异常被 e.printStackTrace() 接住程序并不会崩但后面 getConnection 时因为没有驱动注册可能会报 No suitable driver。如果你看到的是一闪而过多半是异常没有被 catch直接向外抛出了。排查时可以先在 main 方法最外层加一个 try-catch(Exception e) 打印完整堆栈就能把隐藏的异常揪出来。拿到源码后我都会建议同学先加这一层保护再运行不是代码不行而是交付环境和自己的环境经常有差异多一层输出比干瞪眼强。5.5 现象课设报告和源代码对不上答辩时被老师问住这个坑不发生在运行阶段而是发生在答辩现场。资源包里有一份 docx 课设报告报告里的功能模块图写的是一套源代码里类名的包路径是另一套报告里贴的数据库设计表和 commodity.sql 里的实际字段不一样。这种情况在接单交付的源码里经常出现因为项目改过多轮报告却没同步更新。解决办法是在答辩前做一次完整的一致性核对。打开报告找到“系统功能结构图”然后把源码中 src 目录下的包名和类名列出来逐项对照。比如报告写“包括登录模块、商品添加、商品修改、入库出库、查询统计”你就要在代码里找到对应的 MainFrame、LoginFrame、GoodsManager 等类确认每个功能点都在代码里有入口。数据库设计部分单独核对。报告里的表格列出字段名、类型、说明你打开 commodity.sql 建表语句逐字段比对。不一致的地方优先改代码让它去适配脚本因为脚本已经导入数据库了改脚本重新导数据反而费时间。改完代码后把报告里的字段说明也跟着改一下保持文档和代码一致。如果老师翻报告问“这个字段为什么存在”你至少能指着代码说出它的作用。报告不要求完美但要求自洽这是一条最实在的答辩经验。6. 进阶给库存系统加一个低库存预警与 CSV 导出6.1 用 Swing Timer 做低库存轮询课设做成基本功能后想加分可以加一个低库存预警。Swing 里的 Timer 可以定时执行一个动作正好用来做库存轮询。代码很短Timer timer new Timer(5000, e - { int lowCount DBHelper.countLowStock(); if (lowCount 0) { statusLabel.setText(当前有 lowCount 种商品低库存); } }); timer.start();这段代码每 5 秒查一次数据库统计 stock 小于 min_stock 的商品种类数然后更新到主界面的状态栏。注意 Timer 的回调是跑在事件分发线程里的直接改界面不会报并发错误。countLowStock 方法里的 SQL 大致是SELECT COUNT(*) FROM goods WHERE stock min_stock;5000 是毫秒数课设演示时可以设短一点效果明显实际使用设 30000 更合理避免频繁访问数据库。这个功能会用到上次建表时预留的 min_stock 字段正好能讲一句“我在设计表时就想到了预警需求”逻辑闭环。6.2 把 JTable 数据导出为 CSV另一个容易讲清楚的进阶功能是把库存列表导出成 CSV 文件。用 java.io 的 BufferedWriter 就能实现不依赖第三方库try (BufferedWriter writer Files.newBufferedWriter(Paths.get(inventory.csv))) { writer.write(商品名,库存,最低库存); writer.newLine(); for (int i 0; i table.getRowCount(); i) { writer.write(table.getValueAt(i, 1) , table.getValueAt(i, 3) , table.getValueAt(i, 4)); writer.newLine(); } }这段代码从 JTable 里按行取当前界面展示的数据写入 CSV 文件。导出功能的加分点在于你能主动讲到 JTable 的 getValueAt 是按行列取值课堂上刚好讲过老师不会觉得超纲。需要注意 CSV 文件的内容如果含中文用 Excel 打开可能乱码原因是 Excel 默认用 ANSI 编码读取。当初我验收课设项目时最在意的不是功能数量而是每个功能你能否从界面触发说到数据库语句。低库存预警和 CSV 导出这两个扩展点正好覆盖了 Swing Timer 和文件流两个知识点放到答辩时主动讲出来很容易把老师往你熟悉的领域引导。我自己每次拿到这类带数据库的课设源码都会先看有没有 min_stock 这类预留字段有的话说明作者留了扩展空间加这些功能会顺手很多。从那以后我做课设也习惯先想清楚哪个字段能支撑附加功能再动手写界面。希望这套拆解思路帮到你。本文还有配套的精品资源点击获取