Java超市管理系统实战:Eclipse+MySQL环境搭建与JDBC事务开发指南
发布时间:2026/10/1 11:54:00来源:尧图网络
简介这套基于Eclipse与MySQL开发的Java超市管理系统面向Java学习者、课程设计者及需要快速搭建进销存项目的开发者。系统完整覆盖商品进销存管理包含商品销售、采购订单跟踪、供应商管理、库存预警与销售统计报表并按角色拆分为管理员和收银员两个操作界面适合毕业设计、实训项目或中小超市信息化改造参考。压缩包共378个文件含49个Java源码、56个JSP页面、98个编译后的class文件另附SQL脚本、XML配置、jar依赖及CSS/JS等前端资源整体约10.37MB目录结构清晰导入Eclipse配合MySQL即可运行。已有2384人学习下载。通过源码可梳理登录验证、商品增删改查、库存实时更新、销售排行与毛利分析等完整业务逻辑也能直接修改数据表结构扩展会员、促销等模块是理解JavaWeb分层开发与数据库关联查询的实用样例。1. 用EclipseMySQL跑通超市管理系统先搞懂这几件事Java超市管理系统EclipseMySQL是Java课程设计和自学入门里出现频率最高的项目题。它的目标很直白用Java写界面和业务逻辑用MySQL存商品、库存和销售记录再用JDBC把两者接通跑出一个能在本地收银、查库存、看报表的小系统。难点不在超市业务本身而在于环境版本联动和JDBC参数配置——这也是我把这篇笔记的重点放在“跑通”上的原因。适合谁看第一次用Eclipse连MySQL的人、被课程设计追着走的学生、想系统练JDBC和SQL的转行开发者。你不需要提前会Spring也不需要懂分布式把JDK、Eclipse、MySQL这三个软件的版本关系理顺后面照做就能把项目立起来。下文按环境搭建、数据库设计、JDBC落地、排错清单、交付前验证的顺序展开每一步都有可直接复制的代码和参数。2. 环境搭对后面少流三次泪JDK、Eclipse和MySQL的版本配合第一次做这类项目的人九成卡点不在Java代码上而在“环境启动失败”和“数据库连接不上”。这一章把三个软件的版本关系和安装参数说清楚能省下大量搜索报错的时间。2.1 为什么是EclipseMySQL而不是IDEAOracle先说明如果以后进公司实习或正式开发IDEA和Oracle都很常见。但课程设计、毕业设计和练手项目选EclipseMySQL道理很实在Eclipse免费内存占用比IDEA旗舰版低老机器也能流畅跑配合WindowBuilder插件可以直接拖拽出Swing窗口写超市收银界面比手写布局快很多。MySQL社区版免费安装包体积小而Oracle安装包动辄好几个GB配置步骤也更繁琐不适合作为教学型项目的数据库。再加上学校机房和大量教程默认这套组合遇到问题更容易搜到对应答案。这个选择不是性能最优解而是“最少折腾”的组合。但有一点要提前说清楚工具只是壳JDBC写法和SQL设计才是你真正学到的东西。后面代码换到IDEA上完全通用不需要重写。2.2 版本配合参考与安装关键参数先给出一份版本配合表这是我在多台机器上验证过的组合JDK版本Eclipse版本MySQL版本驱动选择建议JDK 8Eclipse 2020-06 及以上均可MySQL 5.7 / 8.0mysql-connector-java-5.1.49 或 8.0.xJDK 11Eclipse 2020-09 及以上MySQL 8.0mysql-connector-j 8.0.xJDK 17Eclipse 2022-06 及以上MySQL 8.0mysql-connector-j 8.x几个选型要点JDK 8 MySQL 5.7 是课设最常见的组合网上现成博客最多遇到问题最好搜。如果已经装了 MySQL 8.0驱动务必用 8.x 版本否则老驱动会报SSL或认证插件错误具体见第4章。Eclipse安装时勾选“Eclipse IDE for Java Developers”就够不需要企业版JDK装好后Eclipse会自动识别JRE。安装步骤给最小集装JDK 8或11配置 JAVA_HOME 指向安装目录PATH 里追加 %JAVA_HOME%\bin运行Eclipse安装器选择 Eclipse IDE for Java Developers工作区放到D盘非中文目录路径里别带中文和空格避免后面出玄学问题装MySQL安装时选择 Server and Client 组件端口默认3306编码选 utf8mb4如果安装器没提供编码选项后面建库时通过SQL指定也可以root密码记到一个临时文件里建议短一点、不含特殊符号比如 root/123456方便后面JDBC测试。装完后在命令行验证java -version mysql -u root -pjava -version 输出版本号说明JDK环境变量生效MySQL命令行能进入并执行 show databases; 看到 information_schema、mysql、performance_schema、sys 四个库说明MySQL服务正常。如果在Linux上提示 error 2002 cant connect to local mysql server through socket /tmp/mysql.sock通常是MySQL服务没启动systemctl start mysqld 即可这个报错在Windows原生环境里较少见。2.3 Eclipse建项目的第一个最小步骤先让连接跑通很多同学一上来就建Dynamic Web Project配置Tomcat失败后心态崩掉。做超市管理系统第一步应该是一个最普通的Java ProjectFile → New → Java Project项目名 shop_system在项目里新建 lib 文件夹把MySQL驱动jar复制进去右键 jar → Build Path → Add to Build Path新建一个类 TestConnection.java写最小main方法测试连接确认后再开始写业务。import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class TestConnection { public static void main(String[] args) { String url jdbc:mysql://localhost:3306/shop_system ?useUnicodetruecharacterEncodingutf8 useSSLfalseserverTimezoneAsia/Shanghai; String user root; String password 123456; try { Class.forName(com.mysql.cj.jdbc.Driver); Connection conn DriverManager.getConnection(url, user, password); System.out.println(连接成功); conn.close(); } catch (ClassNotFoundException e) { System.out.println(驱动类没找到检查jar是否加入Build Path); e.printStackTrace(); } catch (SQLException e) { System.out.println(连接失败检查URL/用户名/密码/MySQL服务); e.printStackTrace(); } } }参数说明serverTimezoneAsia/Shanghai 是因为 MySQL 8.0 默认时区是UTCJava驱动拿到的连接时间会差8小时useSSLfalse 用于本地开发关闭SSL握手避免“mysql ssl连接错误”。Class.forName 在8.x驱动里可以省略但写上能让整个加载流程更清晰老教程迁移过来时也不容易漏。执行后如果控制台打出“连接成功”说明环境闭环已经通了后面写业务代码心里有底。做到这一步有人会遇到“找不到或无法加载主类”的报错通常是右键Run As时选错了启动配置或者建了Web项目但没有Server Runtime这个坑放在第5章专门讲。3. 把数据库先立住超市进销存的表设计与建表SQL先有表后有代码。做管理系统我习惯先把数据库跑通再回头写Java端。数据库设计不合理的项目后面改起来比重写还痛苦。3.1 五张核心表围绕商品、供应商和销售流水建模超市管理系统最少需要五张表商品分类表、商品表、供应商表、销售单表、销售明细表。前三个是基础数据后两个是每次收银产生的流水也是“进销存”里的“销”。category 保存分类信息goods 保存商品名称、条码、价格、库存supplier 记录供应商sale_order 是每次结账的“头表”记总金额、结账时间、操作员sale_item 是“明细表”一行一个商品记购买数量、单价、小计金额。为什么要拆成订单和明细两张表因为一次结账会买多个商品sale_order 保存这一单的总额和时间sale_item 一行一个商品。统计“今天卖了多少单”看 sale_order“某个商品卖了多少”看 sale_item查询时两表JOIN即可不用每单存一堆重复信息。库存直接放在 goods.stock 字段课程设计阶段足够。如果以后要加“进货入库”功能再建 purchase 表存进货记录不动商品表结构。3.2 建表SQL字符集决定中文能不能存先建数据库再建表顺序不要颠倒。下面是我常用的初始化脚本CREATE DATABASE IF NOT EXISTS shop_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE shop_system; CREATE TABLE category ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL UNIQUE, remark VARCHAR(200) DEFAULT ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE supplier ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, contact VARCHAR(50) DEFAULT , phone VARCHAR(20) DEFAULT , address VARCHAR(200) DEFAULT ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE goods ( id INT AUTO_INCREMENT PRIMARY KEY, category_id INT NOT NULL, name VARCHAR(100) NOT NULL, barcode VARCHAR(30) DEFAULT , price DECIMAL(10,2) NOT NULL, stock INT UNSIGNED DEFAULT 0, status TINYINT DEFAULT 1, INDEX idx_goods_category (category_id), CONSTRAINT fk_goods_category FOREIGN KEY (category_id) REFERENCES category(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE sale_order ( id INT AUTO_INCREMENT PRIMARY KEY, order_no VARCHAR(20) NOT NULL, total_amount DECIMAL(10,2) NOT NULL, sale_time DATETIME NOT NULL, operator VARCHAR(50) DEFAULT , INDEX idx_order_time (sale_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE sale_item ( id INT AUTO_INCREMENT PRIMARY KEY, order_id INT NOT NULL, goods_id INT NOT NULL, quantity INT UNSIGNED NOT NULL, price DECIMAL(10,2) NOT NULL, amount DECIMAL(10,2) NOT NULL, INDEX idx_item_goods (goods_id), CONSTRAINT fk_item_order FOREIGN KEY (order_id) REFERENCES sale_order(id), CONSTRAINT fk_item_goods FOREIGN KEY (goods_id) REFERENCES goods(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;几个容易忽略的参数全部用 InnoDB 引擎因为后面结账要开事务MyISAM 不支持事务一个订单成功一个库存没减数据就烂了。金额用 DECIMAL(10,2) 而不是 DOUBLEDOUBLE 有浮点精度问题累计金额时会出现 0.10.20.30000000000000004 这种结果。goods.stock 设置 DEFAULT 0 是有意的新建商品时初始库存为0是正常业务如果字段没默认值插入语句少写 stock 就会直接报错。barcode 用 VARCHAR(30) 而不是 INT条形码可能以0开头整型会丢掉前导零。外键约束建议保留能防止商品被删掉后销售明细还在引用不存在的记录。MySQL 8.0 的默认排序规则是 utf8mb4_0900_ai_ci而 5.7 常用 utf8mb4_general_ci。为了兼容我建库时显式指定 COLLATE utf8mb4_general_ci避免不同版本执行脚本时排序规则不一致。3.3 初始化数据先喂饱再开发不要空表开发先造一批数据后面写列表、查询、结账时才有对象可测。下面是基础数据INSERT INTO category (name, remark) VALUES (饮料, 瓶装和罐装饮品), (零食, 膨化食品、糖果等); INSERT INTO supplier (name, contact, phone, address) VALUES (本地食品批发, 张三, 13900000000, 城东物流园A区); INSERT INTO goods (category_id, name, barcode, price, stock) VALUES (1, 矿泉水550ml, 690000000001, 2.00, 100), (1, 可乐330ml, 690000000002, 3.50, 80), (2, 薯片原味, 690000000003, 6.50, 50);插入完成后执行 SELECT * FROM goods; 确认数据正常、中文不乱码再继续写Java。如果你用 Navicat 或 MySQL Workbench 执行脚本执行前注意连接编码很多乱码问题在建库阶段就埋下了。4. 写JDBC的正确姿势连接参数、预编译和事务提交表结构就绪进入代码阶段。这一章按“连接→封装→事务”三步走代码可以直接抄进项目。4.1 驱动版本与URL参数mysql ssl连接错误是怎么来的先解决这个高频报错。MySQL 5.7 默认不强制SSLMySQL 8.0 默认开启SSL老驱动连接时就会在握手阶段报错。常见报错文字有 SSL connection error 和 Public Key Retrieval is not allowed前者是因为URL没关 useSSL后者是因为 MySQL 8 的 caching_sha2_password 认证需要先获取公钥而连接参数里没开 allowPublicKeyRetrieval。于是连接参数应该写成这样String url jdbc:mysql://localhost:3306/shop_system ?useUnicodetruecharacterEncodingutf8 useSSLfalse serverTimezoneAsia/Shanghai allowPublicKeyRetrievaltrue;参数逐个说明useUnicodetrue 和 characterEncodingutf8 告诉MySQL用UTF-8传输避免中文乱码useSSLfalse 是本地开发环境关闭SSL校验生产环境应交给DBA统一规划serverTimezoneAsia/Shanghai 指定时区防止写入DATETIME字段时差8小时allowPublicKeyRetrievaltrue 配合MySQL 8的认证插件使用本地连接风险可控生产环境换用SSL证书。驱动jar版本也要注意老教程下载的是 mysql-connector-java-5.1.49驱动类名是 com.mysql.jdbc.Driver8.x 版本包名变成 com.mysql.cj.jdbc.Driver。如果项目里用8.x驱动但代码写 com.mysql.jdbc.Driver有时能兼容但碰到SSL问题会非常疑惑。4.2 DBUtil把连接和关闭封装起来每个DAO里都写 DriverManager.getConnection 会非常啰嗦每次 new 一个 Connection 的开销也不小。我的做法是先封装一个连接工具类import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class DBUtil { private static final String URL jdbc:mysql://localhost:3306/shop_system ?useUnicodetruecharacterEncodingutf8 useSSLfalseserverTimezoneAsia/Shanghai allowPublicKeyRetrievaltrue; private static final String USER root; private static final String PASSWORD 123456; static { try { Class.forName(com.mysql.cj.jdbc.Driver); } catch (ClassNotFoundException e) { throw new ExceptionInInitializerError(MySQL驱动加载失败检查jar包是否正确); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } public static void close(Connection conn, Statement stmt, ResultSet rs) { try { if (rs ! null) rs.close(); } catch (SQLException ignored) {} try { if (stmt ! null) stmt.close(); } catch (SQLException ignored) {} try { if (conn ! null) conn.close(); } catch (SQLException ignored) {} } }逻辑说明static 块在类第一次被加载时执行一次驱动注册只做一遍getConnection 用 DriverManager 原生实现适合课程设计和并发量很小的系统close 方法统一关闭顺序为 ResultSet → Statement → Connection顺序反了会报“连接已关闭”的二次错误。关闭方法里用空catch而不是打印堆栈是因为关闭失败通常不影响主流程避免在finally里又抛异常掩盖原始错误。如果以后要把项目做成正式上线的东西建议换 HikariCP 连接池连接获取和归还由池管理性能差异很大。但学习阶段先把 DriverManager 流程吃透再过渡到连接池会顺很多。4.3 PreparedStatement 与事务一次结账要同生共死超市系统最核心的结账逻辑是插一笔销售单、插若干条销售明细、把每个商品的库存扣掉。这三件事任何一个失败都应该全部回滚。“java怎么保证数据一致性”在JDBC层面答案就是事务所有SQL在同一个Connection上执行要么全部成功要么全部回滚。给一个简化的结账方法import java.math.BigDecimal; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; import java.util.List; public class SaleDao { public void createOrder(String orderNo, String operator, ListOrderItem items) throws SQLException { Connection conn null; PreparedStatement psOrder null; PreparedStatement psItem null; PreparedStatement psStock null; try { conn DBUtil.getConnection(); // 关闭自动提交开启事务 conn.setAutoCommit(false); psOrder conn.prepareStatement( INSERT INTO sale_order(order_no, total_amount, sale_time, operator) VALUES (?, ?, ?, ?)); // 总金额由调用方计算示例传0 psOrder.setString(1, orderNo); psOrder.setBigDecimal(2, BigDecimal.ZERO); psOrder.setTimestamp(3, new Timestamp(System.currentTimeMillis())); psOrder.setString(4, operator); psOrder.executeUpdate(); psItem conn.prepareStatement( INSERT INTO sale_item(order_id, goods_id, quantity, price, amount) VALUES (?, ?, ?, ?, ?)); psStock conn.prepareStatement( UPDATE goods SET stock stock - ? WHERE id ? AND stock ?); for (OrderItem item : items) { psItem.setInt(1, getOrderId(orderNo)); psItem.setInt(2, item.getGoodsId()); psItem.setInt(3, item.getQuantity()); psItem.setBigDecimal(4, item.getPrice()); psItem.setBigDecimal(5, item.getAmount()); psItem.addBatch(); psStock.setInt(1, item.getQuantity()); psStock.setInt(2, item.getGoodsId()); psStock.setInt(3, item.getQuantity()); int rows psStock.executeUpdate(); if (rows 0) { throw new SQLException(商品 item.getGoodsId() 库存不足); } } psItem.executeBatch(); conn.commit(); } catch (SQLException e) { if (conn ! null) { try { conn.rollback(); } catch (SQLException ignored) {} } throw e; } finally { DBUtil.close(conn, psOrder, null); // psItem、psStock 需要单独关闭示例为了突出重点省略 } } private int getOrderId(String orderNo) throws SQLException { return 0; // 实际应用用 PreparedStatement.RETURN_GENERATED_KEYS 取自增主键 } }关键点conn.setAutoCommit(false) 是事务的起点commit 在所有 insert 和 update 成功后执行。库存扣减的 UPDATE 语句带上 AND stock ?让数据库在一条SQL里同时完成“扣减”和“校验”比先查库存再改数量更可靠。一旦某一步抛异常rollback 会把已执行的 insert 全部撤销避免“订单录了库存没减”。代码里 getOrderId 是示意生产项目应该在插入 sale_order 后调用 PreparedStatement 的 RETURN_GENERATED_KEYS 拿到自增主键而不是用业务单号反查主键这个习惯要尽早养成。还有一个新手经常踩的坑如果每次SQL都用 DBUtil.getConnection() 新开连接事务就失效了。一个事务里的所有操作必须在同一个 Connection 上执行所以这个方法的 conn 从开头拿到结束一直传下去而不是方法内部各连各的。排查“事务回滚无效”时先检查是不是用了多个连接。5. 排查清单Eclipse与MySQL联调时我踩过的5个高频坑带课设这两年里大家翻车的地方高度雷同。下面五条都按“现象→原因→解决”写当排查手册用。5.1 eclipse 找不到或无法加载主类 org.apache.catalina.startup.bootstrap现象点击运行控制台报“找不到或无法加载主类 org.apache.catalina.startup.bootstrap”。原因这句话表面看是Tomcat类找不到实际有几类可能建的是Dynamic Web Project但没添加Tomcat Server Runtime或者右键 Run As 时选成了 Server 启动Tomcat配置指向了空目录或者项目被当成普通Java项目用main方法启动但类名写错。解决先判断你做的是桌面版还是Web版。桌面版直接从 src 下找到带 main 的类右键 Run As → Java Application不经Server启动路径。Web版则在底部Servers视图里 New Server选对应Tomcat版本把项目 Add 进去再 Run As → Run on Server。如果你只是练JDBC不打算做Web项目建议忽略这个报错专注桌面版代码。5.2 mysql ssl连接错误本地开发请直接关SSL现象启动项目连接数据库控制台出现 SSL connection error 或 Public Key Retrieval is not allowed。原因MySQL 8 默认使用 caching_sha2_password 认证默认开启SSL老驱动或没配置连接参数会在握手阶段失败。此时不是密码错了是参数没对上。解决给URL加上 ?useSSLfalseallowPublicKeyRetrievaltrue驱动换成 mysql-connector-j 8.x。加了参数还报错时先检查jar包是否真的在Build Path里。Eclipse里把jar复制进lib文件夹后还需要右键 jar → Build Path → Add to Build Path否则运行时必报类找不到。5.3 Access denied for user rootlocalhost先命令行再查代码现象JDBC运行报 Access denied for user ‘root’‘localhost’ (using password: YES)。原因大部分情况是密码不对或者端口不是3306。Windows上有人装过多个MySQL服务3306被老版本占用新装的MySQL跑在3307代码连3306自然失败。解决先在命令行执行 mysql -u root -p 验证密码。命令行都进不去就把密码重置临时给MySQL服务加 --skip-grant-tables 参数重启然后 UPDATE mysql.user SET authentication_string... WHERE Userroot改完关掉该参数再重启服务否则裸奔状态下很危险。端口问题则把URL里的3306改成实际端口。localhost 和 127.0.0.1 在MySQL里可能被当成不同host代码里用localhost连不上时可以试 jdbc:mysql://127.0.0.1:3306/...。5.4 Unknown database 或 Table doesnt existSQL脚本没跑全现象运行时提示 Unknown database ‘shop_system’或 Table ‘sale_item’ doesn’t exist。原因建了库但没执行建表脚本或建表脚本执行时USE语句没有选中目标库或建表因外键顺序问题报错后后续表没建成。解决把第3章的SQL脚本从头到尾按顺序执行一遍。用Navicat或MySQL Workbench打开脚本先执行 CREATE DATABASE 和 USE 语句再建表。中途有表建失败用 SHOW TABLES; 看哪些缺失。注意建表顺序先建 category、supplier再建 goods最后建 sale_order 和 sale_item外键引用的表不能晚于引用它的表。5.5 控制台和数据库中文乱码三处编码必须一致现象插入的中文在MySQL里变成问号或者查询回显乱码。数据没坏是编码传输不一致的玄学问题。原因MySQL连接默认字符集可能是latin1Eclipse工作区默认GBK而建库用了utf8mb4三处不一致导致中文绕一圈就乱。解决按顺序检查三处。建库语句带 DEFAULT CHARACTER SET utf8mb4JDBC URL里带 useUnicodetruecharacterEncodingutf8Eclipse的 Window → Preferences → General → Workspace把 Text file encoding 改成 UTF-8。还乱就再给运行配置加 -Dfile.encodingUTF-8。老数据已经乱码直接把测试库drop重建不用心疼测试数据。6. 让系统更像成品登录拦截、销售统计与交付前的验收到这个阶段功能通常已经能跑。我最后会做三件事让它从“能跑”变成“能演示”。第一登录判断不要只写在按钮点击事件里做字符串比较。把用户表抽象成 UserDao登录方法返回用户对象如果做Web版登录成功后把用户信息放进Session再用一个Filter统一拦截未登录请求。这样后续加权限、加日志都不需要改动每个页面。拦截逻辑大致是这样public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpServletResponse response (HttpServletResponse) resp; if (request.getSession().getAttribute(user) null) { response.sendRedirect(request.getContextPath() /login.jsp); return; } chain.doFilter(request, response); }这个Filter挡住所有未登录请求只有session里有user才放行。登录需求看起来简单但很多人的实现是每个页面复制一段if判断模块一多就漏。集中拦截更接近正式项目。第二销售统计直接用SQL做不要在Java里循环加。统计今天的销售额和订单数一条语句就够了SELECT COUNT(*) AS orderCount, SUM(total_amount) AS totalAmount FROM sale_order WHERE DATE(sale_time) CURDATE();按商品分组统计销量就 GROUP BY goods_id 再JOIN goods表取名字。SQL写清楚后Java端遍历ResultSet就能出表格。如果想把报表导出成Excel用Apache POI写导出工具类比做Word图表更实用——超市管理系统的报表评阅老师通常要Excel不是Word里嵌一张图。第三交付前做一次“清库重建全流程走查”。把数据库drop掉再重跑建库脚本确认新环境也能初始化成功然后走一遍登录→新增商品→结账→查看库存四个主流程把窗口大小调到1000×720再跑一遍确保默认分辨率下按钮不挤压。这个习惯救了我好几次课设演示用的电脑经常和开发机不一样残留数据也会让评委误以为功能异常。这些年指导课设见得最多的不是业务写不出来而是环境问题、编码问题和事务问题在三更半夜反复折腾。把上面几条固化成本能你会少掉很多头发。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网