ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

JavaEE仓库管理系统实战:Servlet+Oracle从环境搭建到避坑指南

JavaEE仓库管理系统实战:Servlet+Oracle从环境搭建到避坑指南 简介这是一套面向高校学生与Java Web进阶学习者的仓库管理系统完整项目资料可作为毕业设计、课程设计、大作业或工程实训的参考方案帮助解决从需求分析到系统落地的全流程问题。系统基于JavaEE与Oracle实现涵盖入库、出库、商品查看、用户注册及个人信息管理等核心模块结构清晰适合对照学习Servlet、JSP与数据库交互的典型写法。压缩包共191个文件约60.22MB包含31个java源文件、31个class编译文件、24个jsp页面、12个xml配置、5个jar依赖及2个properties配置另有gif与png界面截图、mp4演示视频、sql建库脚本、docx论文文档和pptx答辩材料覆盖源码、数据库、论文与视频全链路。目前已有173人学习下载读者可借此快速理解分层结构、复用建表语句、参考论文框架并对照录屏完成环境搭建与功能验证。1. 仓库管理系统跑通记从 Servlet 到 Oracle 的完整链路很多同学拿到「基于 JavaEE Oracle 的仓库管理系统」这类毕设资源时第一反应是打开 IDE 直接 Run结果卡在数据库连不上、Servlet 404、Tomcat 版本不兼容上折腾两天连登录页都进不去。这套资源的定位很明确一套完整的 Web 仓库管理系统覆盖入库、出库、库存查看、用户注册、个人信息管理五个核心模块技术栈是经典 Servlet JSP Oracle附带源码、数据库 SQL、论文和演示视频。它适合两类人——需要交课程设计或毕设的学生以及想拿一个真实 CRUD 项目练手 JavaEE 的初学者。关键点在于这不是 Spring Boot 项目没有自动配置帮你兜底所有 JDBC 连接、Servlet 映射、Session 管理都得自己理清楚。下面按「先跑起来、再改明白、最后避坑」的顺序拆一遍。2. 环境搭建与数据库初始化Oracle 建库和 JDBC 连接怎么配2.1 技术选型为什么是 Servlet Oracle 而不是 SSM这套系统用的是原生 Servlet JSP JDBC没有引入 Spring、MyBatis 这些框架。从学习角度看这反而是好事——你能清楚看到一次请求从浏览器到 Servlet、再到 JDBC、最后落到 Oracle 表的完整链路不会被框架的注解和自动装配遮住。Oracle 作为数据库在高校课程设计里出现频率很高它的 SQL 语法和 MySQL 有差异比如分页要用ROWNUM而不是LIMIT序列要用SEQ.NEXTVAL而不是AUTO_INCREMENT。如果你之前只接触过 MySQL这套资源正好能帮你补齐 Oracle 的基本操作。从项目正文里能看到一批编译后的 class 文件比如AloginServlet.class、CloginServlet.class、InOldGoodsServlet.class、OutGoodsServlet.class这些对应的是管理员登录、客户登录、已有商品入库、商品出库等核心业务。命名规律是「角色/业务 Servlet」A 开头大概率是 Admin管理员C 开头是 Customer客户。理解这个命名规律后你改代码时能快速定位到对应模块。2.2 Oracle 建库与 SQL 脚本导入拿到资源后第一步不是打开 IDE而是先把数据库跑起来。资源里应该有一份.sql文件包含建表和初始数据。常见做法是在 SQL Developer 或 SQLPlus 里执行。先创建一个专用用户避免直接用 system 账号-- 以 sysdba 身份登录后执行 CREATE USER warehouse IDENTIFIED BY warehouse123; GRANT CONNECT, RESOURCE TO warehouse; GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE TO warehouse;然后切换到 warehouse 用户执行资源里的建表脚本。典型表结构大概包括商品表、库存表、入库记录表、出库记录表、用户表。执行时注意脚本里的表空间名称如果脚本写的是某个特定表空间而你本地没有会报ORA-00959: tablespace does not exist把表空间子句删掉或改成USERS即可。-- 连接新用户 CONN warehouse/warehouse123; -- 执行建表脚本假设文件名为 warehouse.sql /path/to/warehouse.sql; -- 验证表是否创建成功 SELECT table_name FROM user_tables;执行完后用SELECT table_name FROM user_tables;确认表都建好了。如果脚本里有序列sequence也检查一下SELECT sequence_name FROM user_sequences;因为 Oracle 插入数据时主键通常靠序列生成序列没建好后面插入会直接报错。2.3 JDBC 连接配置与驱动放置数据库建好后接下来是让 Java 代码连上 Oracle。这套系统用的是 JDBC 直连配置文件通常是一个.properties文件或者在 Servlet 里硬编码。你需要找到类似db.properties或DBUtil.java的文件把 URL、用户名、密码改成你本地的# db.properties 常见配置格式 driveroracle.jdbc.driver.OracleDriver urljdbc:oracle:thin:localhost:1521:orcl usernamewarehouse passwordwarehouse123这里有几个参数要特别注意。localhost:1521是 Oracle 默认监听地址和端口orcl是数据库实例名SID如果你安装时用的是可插拔数据库PDB实例名可能是orclpdb或xe写错了会报ORA-12505: TNS:listener does not currently know of SID given in connect descriptor。驱动 jar 包ojdbc8.jar或ojdbc6.jar必须放到WEB-INF/lib目录下同时加入 IDE 的 Build Path否则运行时会报ClassNotFoundException: oracle.jdbc.driver.OracleDriver。注意Oracle 驱动版本要和 JDK 版本匹配。JDK 8 用 ojdbc8 没问题JDK 11 以上建议用 ojdbc10 或更高版本否则可能遇到 SSL 握手或字符集问题。3. Servlet 映射与业务模块拆解入库出库到底怎么走3.1 web.xml 配置与 Servlet 映射关系这套项目没有用注解WebServlet大概率是在web.xml里做 Servlet 映射。打开WEB-INF/web.xml你会看到类似这样的配置servlet servlet-nameAloginServlet/servlet-name servlet-classcom.warehouse.servlet.AloginServlet/servlet-class /servlet servlet-mapping servlet-nameAloginServlet/servlet-name url-pattern/alogin/url-pattern /servlet-mapping每个 Servlet 对应一个url-pattern前端 JSP 表单的action属性就指向这个路径。如果你改了包名或类名servlet-class必须同步改否则 Tomcat 启动时会报ClassNotFoundException。常见做法是先把所有 Servlet 映射列一张表对照 class 文件逐个确认Servlet 类名推测功能对应 URLAloginServlet管理员登录/aloginCloginServlet客户登录/cloginAregisterServlet管理员注册/aregisterCregisterServlet客户注册/cregisterGoodsSaveServlet商品保存入库/goodsSaveInOldGoodsServlet已有商品入库/inOldGoodsOutGoodsServlet商品出库/outGoodsACInfServlet管理员信息管理/acInfCInfServlet客户信息管理/cinf这张表是你后续调试的路线图。哪个功能出问题直接定位到对应 Servlet在doPost或doGet方法里打断点。3.2 入库模块的完整数据流入库分两种新商品入库和已有商品入库。新商品入库走GoodsSaveServlet逻辑是先插入商品信息表再插入库存记录已有商品入库走InOldGoodsServlet逻辑是更新库存数量。以新商品入库为例Servlet 里的核心代码大概长这样// GoodsSaveServlet.java 核心逻辑 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(UTF-8); String goodsName request.getParameter(goodsName); String goodsType request.getParameter(goodsType); int quantity Integer.parseInt(request.getParameter(quantity)); double price Double.parseDouble(request.getParameter(price)); Connection conn null; PreparedStatement ps null; try { conn DBUtil.getConnection(); // 先插入商品基本信息 String sql INSERT INTO goods(goods_id, goods_name, goods_type, price) VALUES(seq_goods.NEXTVAL, ?, ?, ?); ps conn.prepareStatement(sql); ps.setString(1, goodsName); ps.setString(2, goodsType); ps.setDouble(3, price); ps.executeUpdate(); // 再插入库存记录 // ... 省略库存插入逻辑 } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(conn, ps, null); } }这里的关键参数是seq_goods.NEXTVALOracle 用序列生成主键你必须确认数据库里确实建了这个序列。如果报ORA-02289: sequence does not exist说明序列名对不上或者没建。另外request.setCharacterEncoding(UTF-8)必须放在所有getParameter之前否则中文商品名会乱码。3.3 出库模块与库存校验逻辑出库走OutGoodsServlet核心逻辑是先查当前库存判断是否足够足够才执行扣减。常见写法// 出库前先校验库存 String checkSql SELECT quantity FROM stock WHERE goods_id ?; ps conn.prepareStatement(checkSql); ps.setInt(1, goodsId); ResultSet rs ps.executeQuery(); if (rs.next()) { int currentQty rs.getInt(quantity); if (currentQty outQty) { request.setAttribute(msg, 库存不足当前库存 currentQty); request.getRequestDispatcher(outGoods.jsp).forward(request, response); return; } // 库存足够执行扣减 String updateSql UPDATE stock SET quantity quantity - ? WHERE goods_id ?; // ... 执行更新 }这段逻辑里最容易翻车的地方是并发。如果两个人同时出库同一商品都查到库存足够然后都执行扣减就会出现超卖。课程设计级别通常不要求处理并发但如果你要在论文里体现思考深度可以提一下用SELECT ... FOR UPDATE加行锁或者把校验和扣减合并成一条UPDATE stock SET quantity quantity - ? WHERE goods_id ? AND quantity ?根据返回的受影响行数判断是否成功。4. 论文与视频的配合用法怎么把资源变成自己的东西4.1 论文结构拆解与复用边界资源里附带的论文通常包含需求分析、系统设计、数据库设计、功能实现、测试这几个章节。直接照抄风险很大查重过不了。正确的用法是把论文当成「设计文档」来读——重点看它的 E-R 图、表结构设计、模块划分思路然后用自己的话重新组织。比如论文里的数据流图DFD你可以用 Visio 或 Draw.io 重画一遍改一下布局和标注既理解了系统又避免了重复。数据库设计部分是最值得参考的。论文里一般会列出每张表的字段、类型、约束你可以对照 SQL 脚本逐个核对确认字段长度、主外键关系是否合理。如果发现论文里写了某个字段但 SQL 里没有或者反过来说明资源本身有版本差异以能跑通的 SQL 为准。4.2 视频的定位不是教程是操作参照附带的视频大概率是系统功能演示不是手把手教你写代码的教程。它的价值在于让你快速看到「系统跑起来应该是什么样」——登录页长什么样、入库表单有哪些字段、出库成功后跳转到哪个页面。当你自己搭环境卡住时对照视频里的操作流程能快速判断是配置问题还是代码逻辑问题。比如视频里点「入库」后跳转到了成功页而你这边报 500那大概率是数据库连接或 SQL 语句的问题而不是前端页面写错了。提示看视频时留意 URL 变化和页面跳转路径这些信息能帮你反推web.xml里的映射配置是否正确。5. 避坑与排查那些让我加班到凌晨的报错5.1 常见问题一Tomcat 启动报 ClassNotFoundException现象Tomcat 启动时控制台刷java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver或某个 Servlet 类找不到。原因驱动 jar 没放到WEB-INF/lib下或者 IDE 的 Build Path 里没有加入。Servlet 类找不到通常是因为web.xml里的servlet-class写的是全限定名但实际包名不一致。解决确认ojdbc8.jar在WEB-INF/lib目录下同时在 IDE 里右键项目 → Build Path → Add External JARs 加入。Servlet 类名对照WEB-INF/classes下编译后的目录结构逐个核对。5.2 常见问题二中文乱码从请求到响应全链路现象入库商品名显示为?????或乱码字符。原因JSP 页面编码、Servlet 请求编码、数据库字符集三者不一致。Oracle 安装时如果字符集选的是WE8ISO8859P1而不是AL32UTF8中文存储就会出问题。解决JSP 页面头部加% page contentTypetext/html;charsetUTF-8 %Servlet 里request.setCharacterEncoding(UTF-8)和response.setContentType(text/html;charsetUTF-8)都要加。数据库层面用SELECT * FROM nls_database_parameters WHERE parameterNLS_CHARACTERSET;确认字符集如果不是 UTF-8 相关建库时就要选对。5.3 常见问题三ORA-12505 监听器不认识 SID现象JDBC 连接时报ORA-12505: TNS:listener does not currently know of SID given in connect descriptor。原因连接 URL 里的 SID 写错了。Oracle 安装时如果创建的是可插拔数据库SID 和你以为的不一样。解决用lsnrctl status查看监听器实际注册的实例名或者查SELECT instance_name FROM v$instance;把 URL 里的 SID 改成实际值。如果是 PDBURL 格式要改成jdbc:oracle:thin:localhost:1521/orclpdb用服务名而非 SID。5.4 常见问题四序列不存在导致插入失败现象执行入库操作时报ORA-02289: sequence does not exist。原因SQL 脚本里的序列创建语句没执行成功或者序列名和代码里写的不一致。解决用SELECT sequence_name FROM user_sequences;查看已有序列对照代码里的seq_xxx.NEXTVAL逐个确认。缺哪个补建哪个CREATE SEQUENCE seq_goods START WITH 1 INCREMENT BY 1;。5.5 常见问题五JSP 页面 404 但 Servlet 没报错现象浏览器访问某个页面返回 404但 Tomcat 控制台没有异常。原因JSP 文件放错了目录。这套项目大概率是 JSP 放在 WebContent 根目录或/pages下如果放到了WEB-INF里面外部直接访问就会 404。解决确认 JSP 文件不在WEB-INF目录下除非是通过 Servlet forward 过去的。检查web.xml的welcome-file-list配置确认默认首页指向正确的 JSP。6. 进阶技巧用 Oracle 分页和连接池把系统提一个档次课程设计级别的系统通常用Statement直接拼 SQL分页靠ROWNUM嵌套两层连接靠DriverManager每次新建。这套资源大概率也是这样。如果你想让论文的「系统优化」章节有东西可写有两个方向可以动手改。第一个是 Oracle 分页的规范写法。很多同学写分页会写成SELECT * FROM goods WHERE ROWNUM 10这只能取前 10 条没法取第 11 到 20 条。正确做法是嵌套子查询-- 查询第 2 页每页 10 条即第 11-20 条 SELECT * FROM ( SELECT g.*, ROWNUM rn FROM ( SELECT * FROM goods ORDER BY goods_id ) g WHERE ROWNUM 20 ) WHERE rn 10;内层排序、中层限制上界、外层过滤下界三层缺一不可。如果你用 Oracle 12c 以上可以直接用OFFSET ... FETCH NEXT ... ROWS ONLY语法更简洁但课程设计里用ROWNUM嵌套更能体现你对 Oracle 的理解。第二个是引入数据库连接池。原生DriverManager.getConnection()每次请求都新建连接、关闭连接开销很大。可以引入 Druid 或 DBCP把DBUtil改成从连接池获取// 用 Druid 替换原生 DriverManager public class DBUtil { private static DataSource dataSource; static { try { Properties props new Properties(); props.load(DBUtil.class.getClassLoader() .getResourceAsStream(druid.properties)); dataSource DruidDataSourceFactory.createDataSource(props); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } }对应的druid.properties里配url、username、password、initialSize、maxActive等参数。改完之后你可以在论文里加一节「连接池选型与性能对比」用 JMeter 压测一下改前改后的响应时间数据一摆论文的工程含量就上来了。还有一个容易忽略的点这套系统的 Session 管理。管理员和客户是两套登录体系Session 里存的 key 大概率是admin和customer。如果你在出库模块里需要判断当前登录的是谁记得从 Session 里取对应对象别取错了。我一般会在每个需要登录才能访问的 Servlet 开头加一段 Session 校验防止未登录直接通过 URL 访问HttpSession session request.getSession(false); if (session null || session.getAttribute(admin) null) { response.sendRedirect(alogin.jsp); return; }这段代码看着简单但漏掉的话别人直接敲 URL 就能绕过登录操作入库出库答辩时被问到就是硬伤。从那以后我每次拿到这类 Servlet 项目第一件事就是把所有 Servlet 的 Session 校验过一遍确认没有裸奔的接口。希望帮到你。本文还有配套的精品资源点击获取
返回列表