JSP超市管理系统源码拆解:架构、数据库与部署排错

发布时间:2026/9/15 3:50:55
JSP超市管理系统源码拆解:架构、数据库与部署排错 简介JSP超市管理系统是一套基于浏览器/服务器模式的Java Web项目采用Java语言与MySQL数据库开发可在Myeclipse和Tomcat7.0环境中直接部署运行适合Java Web初学者、课程设计或毕业设计参考。系统功能覆盖五大业务模块人事管理支持职工信息和供货商信息的查询、添加、删除、修改销售管理提供销售信息查询与商品销售盘点进货管理实现进货信息的查询与增删改库存管理包含商品信息和库存信息的查询及增删改客户管理支持用户添加、删除和密码修改。各模块结构清晰便于二次开发。资源以rar压缩包形式提供大小约1.06MB内含完整项目源代码、数据库脚本jspsupermarket.sql及数据库配置文件DBO.java导入开发环境后即可快速搭建运行。目前已有1023人学习下载系统内置管理员账号admin可直接登录体验有助于理解动态网页与数据库的交互、系统分层开发以及基础业务功能的实现。1. 一套JSP超市管理系统源码能教会你什么我拆过不少以 JSP Servlet MySQL 为底的课程设计源码这套超市管理系统属于结构很典型、坑也很有代表性的那种。登录页在http://127.0.0.1:8080/supermarket/login.jsp管理员账号密码都是 admin数据库脚本是jspsupermarket.sql系统名直接叫 supermarket。它不像 Spring Boot 项目那样一开始就把 Controller、Service、Mapper 分层铺好而是把 JSP 页面、Java 类、JDBC 连接全部摊开在面前。正因为没有框架包装请求如何在浏览器与 Tomcat 之间流转、SQL 如何拼进 PreparedStatement、事务如何用 Connection 手动控制这些原生的写法都可以直接看到。适合三类人一是课程设计想快速跑通并改出自己系统的学生二是想复习 JSP 和原生 JDBC 的 Java 开发三是需要把老系统翻新成 Spring Boot 的人拿它练手。下面按“架构定位 → 数据建模 → 模块实现 → 部署排错”的顺序把它拆开。2. 架构与请求流转JSP页面里的数据是怎么进到MySQL的2.1 拿到源码后先读目录结构项目拿到手先不要急着启动先把 webapps 下的 supermarket 目录结构读明白。这类 MyEclipse 导出的 Web 工程常见的布局是这样的WebRoot有的叫WebContent下放 JSP 页面WEB-INF/web.xml是部署描述符WEB-INF/lib放依赖的 jar 包Java 源码按包组织数据库连接代码集中在DBO.java。很多新手会犯一个错直接把整个 MyEclipse 工程拖进 Tomcat 的 webapps 目录结果访问 404。正确做法是部署编译后的项目目录而不是把.java源码文件丢进去。先看web.xml里有没有配置欢迎页最常见的写法是这样的welcome-file-list welcome-filelogin.jsp/welcome-file /welcome-file-list这段配置的效果是访问http://127.0.0.1:8080/supermarket/时Tomcat 会自动帮你跳转到login.jsp。welcome-file的查找顺序是从上往下如果第一个文件不存在会继续找下一个。前面那段源码没有给出 web.xml 的具体内容但绝大多数从 MyEclipse 导出的工程都会配这一项没配的话就只能在地址栏手敲完整路径。2.2 登录表单提交后请求如何流转从login.jsp的登录表单看整个请求链路是最直观的。这类系统的写法大多是表单直接提交到另一个 JSP 页面或者提交到一个 LoginServlet。先看表单本身form actionloginCheck.jsp methodpost 用户名input typetext nameusername/ 密码input typepassword namepassword/ input typesubmit value登录/ /form这里action是相对 URL浏览器会相对于当前页面地址拼接出请求地址methodpost是为了避免密码出现在地址栏也绕过了 GET 请求的 URL 长度限制。name属性是前后端约定的参数名后端靠它取值如果改了这个值页面功能会直接断掉。后端接收参数的 JSP 片段通常长这样% request.setCharacterEncoding(UTF-8); String username request.getParameter(username); String password request.getParameter(password); UserDao dao new UserDao(); User user dao.findByUsernameAndPassword(username, password); if (user ! null) { session.setAttribute(loginUser, user); response.sendRedirect(main.jsp); } else { out.println(scriptalert(用户名或密码错误);history.back();/script); } %逻辑上做了三件事取参数、查库验证、根据结果决定跳转还是回退。request.setCharacterEncoding必须写在取参数之前才会生效否则中文用户名在 MySQL 5.0 的老环境下很容易变成问号。session.setAttribute把登录用户放进会话后续页面的权限判断就是从这里读的。sendRedirect是重定向浏览器地址栏会变成main.jsp如果改用forward跳转地址栏不变刷新时表单会重复提交这也是老 JSP 系统里最常见的体验问题。2.3 DBO.java 里集中管理数据库连接数据库配置文件为什么叫 DBO 而不是 DBUtil因为这套源码把“数据库对象”的概念集中在一起所有 DAO 类都通过它拿 Connection。类似系统里配置项基本是四个驱动类、连接串、用户名、密码。配置项示例值改错会报什么错驱动类com.mysql.jdbc.DriverClassNotFoundException连接串jdbc:mysql://127.0.0.1:3306/supermarketCommunications link failure用户名rootAccess denied for user密码和本机 MySQL 一致Access denied for user连接代码的核心部分一般是这样Class.forName(com.mysql.jdbc.Driver); Connection conn DriverManager.getConnection( jdbc:mysql://127.0.0.1:3306/supermarket?useUnicodetruecharacterEncodingutf8, root, 123456);Class.forName的作用是把驱动类加载到 JVMMySQL 5.0 配套的驱动入口就是com.mysql.jdbc.Driver。如果换到 MySQL 8.x驱动类要改成com.mysql.cj.jdbc.Driver连接串里还要追加serverTimezoneAsia/Shanghai否则会直接抛时区异常。这套源码既然指定了 MySQL 5.0那就用 5.1.x 版本的mysql-connector-java最稳妥版本太新反而不一定兼容老语法。3. 数据库拆解jspsupermarket.sql与五个业务模块的表结构3.1 从功能模块反推数据库该有哪些表把源码功能过一遍就能反推出表结构人事管理管职工和供货商销售管理管销售信息盘点进货管理管进货单库存管理管商品和库存客户管理管用户账号。这个库至少要有职工表、供货商表、商品表、进货表、销售表、库存表和用户表用SHOW TABLES可以一眼确认SHOW TABLES; DESC employee;导入jspsupermarket.sql之后先别急着跑系统先把表名和注释过一遍。老项目表名前缀往往比较随意有的是t_employee有的直接叫emp对这些细节心里有数后面写 SQL 时才不会把表名拼错。3.2 职工表和商品表的字段设计示例以职工表为例典型设计是这样的CREATE TABLE employee ( emp_id INT NOT NULL AUTO_INCREMENT, emp_no VARCHAR(20) NOT NULL, emp_name VARCHAR(50) NOT NULL, dept_name VARCHAR(50) DEFAULT 未分配, phone VARCHAR(20), hire_date DATE, PRIMARY KEY (emp_id), UNIQUE KEY uk_emp_no (emp_no) ) ENGINEInnoDB DEFAULT CHARSETutf8;emp_id是自增主键新插入数据时不用显式赋值MySQL 会自动生成emp_no是工号一定要加唯一约束否则录入重复工号会导致数据混乱DEFAULT 未分配处理了部门为空的情况。商品表可以参照这个思路设计但要把价格字段用DECIMAL(10,2)而不是FLOAT避免浮点精度导致前台显示的金额出现多位小数。3.3 导入数据库脚本的三种常用方式命令行导入是兼容性最高的MySQL 5.0 的客户端直接这样操作mysql -u root -p -e CREATE DATABASE supermarket DEFAULT CHARACTER SET utf8; mysql -u root -p supermarket jspsupermarket.sql第一条命令建库并指定 UTF-8 字符集第二条把 SQL 脚本导入。这里有个老坑如果jspsupermarket.sql文件本身是 GBK 编码而库是 UTF-8导入后中文注释和中文数据会乱码。Windows 下用 Navicat 导入时注意在连接属性里把编码切到与脚本一致Linux 下可以用file jspsupermarket.sql先查看脚本编码再决定建库字符集。MySQL 5.0 默认存储引擎是 MyISAM但脚本里如果写了ENGINEInnoDB也没问题InnoDB 支持事务对这个系统的进销存业务会更合适。3.4 销售盘点SQL和索引怎么配合销售盘点是把商品表和销售明细关联起来按维度汇总常用 SQL 如下SELECT s.sale_date, p.prod_name, SUM(s.quantity) AS total_qty, SUM(s.quantity * s.price) AS total_amount FROM sale_detail s JOIN product p ON s.prod_id p.prod_id GROUP BY s.sale_date, p.prod_name ORDER BY s.sale_date DESC;数据量大时这个查询很容易慢sale_date字段作为过滤和排序条件给它加个普通索引即可ALTER TABLE sale_detail ADD INDEX idx_sale_date (sale_date);索引不是加得越多越好像这种进销存系统里最常作为 WHERE 条件的字段才值得加销售表的日期、商品表的商品编号、进货表的供货商编号。加了索引后EXPLAIN SELECT ...能看到key字段命中了idx_sale_date说明查询走索引而不是全表扫描。4. 人事/进货/库存模块的CRUD是怎么落地的4.1 职工列表页JSP和DAO的最小闭环职工信息查询页面的套路是固定的JSP 里写 Java 代码调用 DAO遍历结果集输出到表格。页面的核心循环代码如下% ListEmployee empList new EmployeeDao().findAll(); for (Employee e : empList) { % tr td%e.getEmpNo()%/td td%e.getEmpName()%/td tda hrefempEdit.jsp?id%e.getEmpId()%修改/a/td /tr % } %EmployeeDao().findAll()返回的是封装好的对象列表比直接操作 ResultSet 可读性好很多%e.getEmpNo()%是 JSP 表达式等价于out.print(e.getEmpNo())。需要注意for循环的大括号必须闭合在%和%之间漏掉闭合会导致整个页面语法错误。DAO 层的查询方法常见写法是这样public ListEmployee findAll() { String sql SELECT * FROM employee ORDER BY emp_id; try (Connection conn DBO.getConnection(); PreparedStatement ps conn.prepareStatement(sql); ResultSet rs ps.executeQuery()) { ListEmployee list new ArrayList(); while (rs.next()) { Employee e new Employee(); e.setEmpId(rs.getInt(emp_id)); e.setEmpName(rs.getString(emp_name)); list.add(e); } return list; } }try-with-resources语法会在 try 块结束后自动关闭 Connection、PreparedStatement、ResultSet避免老代码里忘关连接导致连接池耗尽。但要注意 MyEclipse 8.5 里默认编译级别要调到 1.7 以上否则这种语法直接编译不过。rs.getInt和rs.getString的参数是列名如果 SQL 里用了SELECT emp_id AS id这里就要用别名。4.2 增加和修改request.getParameter到SQL参数的映射进货和职工模块的新增表单在 JSP 里是普通 HTML inputcontroller 部分把参数取出来再塞进 INSERT 语句String empName request.getParameter(empName); String empNo request.getParameter(empNo); String phone request.getParameter(phone); String sql INSERT INTO employee(emp_no, emp_name, phone) VALUES(?,?,?); PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, empNo); ps.setString(2, empName); ps.setString(3, phone); ps.executeUpdate();这里用?占位符而不是直接拼接字符串第一个?对应emp_no第二个对应emp_name第三个对应phone顺序必须和 SQL 字段顺序一致。一旦参数顺序写反数据就会错位比如手机号存到姓名里。这种方式也避免了 SQL 注入用户输入里如果带上了单引号setString会把它当作普通字符处理而不是结束字符串再执行一段新的 SQL。修改操作和新增区别不大SQL 换成 UPDATE 并带上主键条件。这里有个值得检查的点老系统里很多用 POST 提交表单但没有判断提交来源外部直接构造 POST 请求就能改数据。如果只想做教学演示这个漏洞可以不动但如果是真实商用必须加 session 权限校验。4.3 删除操作里那个最容易被忽略的坑删除功能的写法看起来最简单String id request.getParameter(id); String sql DELETE FROM employee WHERE emp_id id;这行代码如果直接用参数稍微伪造一下就能把整张表清空。正确的做法是用?占位String sql DELETE FROM employee WHERE emp_id?; ps.setInt(1, Integer.parseInt(id));setInt的第二个参数要求必须是数值类型所以先用Integer.parseInt做类型校验这本身就给非法输入加了一道关卡。生产环境中商品和职工删除还应该检查是否存在关联记录比如商品被采购过就不能直接删否则销售盘点时 JOIN 会产生空数据。4.4 进货和库存联动事务把两张表绑在一起进货单插入和库存更新是两个操作必须放在同一个事务里。常见的事务控制骨架如下conn.setAutoCommit(false); try { String insertSql INSERT INTO purchase(purchase_no, prod_id, quantity, purchase_date) VALUES(?,?,?,?); // 执行进货单插入 String updateSql UPDATE product SET stock stock ? WHERE prod_id ?; // 执行库存累加 conn.commit(); } catch (Exception e) { conn.rollback(); throw e; }conn.setAutoCommit(false)表示关闭自动提交之后执行的 SQL 只有在commit()时才真正生效。如果进货单插入成功但库存更新失败会走rollback()把前面的插入也回滚掉保证两张表的数据永远一致。这套源码里的 DBO.java 默认不会开启事务需要自己在业务代码里控制这也是拆这种老项目时最容易看到破绽的地方。5. 部署到Tomcat 7.0验证顺便把JSP编译后的class找出来5.1 MyEclipse 8.5里完成部署先把 Tomcat 7.0 配置到 MyEclipse 的 Servers 窗口然后在工程上右键选择 Deploy 或直接将编译后的工程目录放到apache-tomcat-7.0.x/webapps下面。启动 Tomcat 后访问http://127.0.0.1:8080/supermarket/login.jsp用 admin/admin 登录。如果 404优先检查 webapps 里是不是真的多了 supermarket 这个目录以及目录下是不是有WEB-INF。5.2 首次访问时JSP被编译成了什么有一个问题很多人不知道答案jsp 编译后的 class 文件保存在哪里。Tomcat 对 JSP 的处理不是直接读文件而是先把 JSP 翻译成 Java 源文件再编译成 class。位置在# Linux/macOS find /opt/tomcat7/work -name *login_jsp* # Windows # 在 Tomcat 安装目录的 work\Catalina\localhost\supermarket\org\apache\jsp\ 下work目录下可以看到login_jsp.java和login_jsp.class。打开login_jsp.java里面_jspService方法对应的就是页面主体out.write输出的就是 HTML 片段。改完 JSP 发现页面没变化时删掉 work 对应目录再重启 Tomcat强制重新编译这是最直接的排查手段。5.3 启动报错对照与排查顺序报错信息原因处理办法ClassNotFoundException: com.mysql.jdbc.DriverMySQL 驱动 jar 没放进 WEB-INF/lib下载mysql-connector-java-5.1.x.jar拷入 libCommunications link failureMySQL 服务没启动或端口不通确认 3306 端口监听netstat -an查看Access denied for user rootlocalhostDBO.java 里的密码与 MySQL 实际密码不一致修改 DBO.java 后重新编译HTTP 404项目部署路径不对检查 webapps 目录和访问 URL 大小写最后提一个验证技巧改数据库配置文件 DBO.java 后必须在 MyEclipse 里重新编译并重启 Tomcat因为源码改动不经过重新编译就不会生效而改 JSP 只需要清理 work 目录就够了这一条能帮你省掉大半无关紧要的重启时间。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询