
简介这套设备维修管理系统采用原生Servlet和JDBC开发是一个典型的JavaWeb后台管理项目面向正在学习JavaWeb的学生也适合作为计算机、数学、电子信息等专业的课程设计、期末大作业或毕设参考。系统围绕设备报修、维修记录、配件资料、客户信息、任务派发等模块展开能帮助读者理解请求转发、表单提交、JDBC增删改查以及分层开发的基本思路下载后无需额外环境即可对照源码学习。压缩包共248个文件内有54个Java源码和对应Class文件、50个JavaScript、17个CSS以及jpg、png图片素材还附带SQL脚本、数据库文件、项目配置和说明文档压缩后约2.84MB目录结构清楚前端样式、交互脚本和后端Servlet逻辑区分明确适合导入IDE后逐步调试。目前已有346人学习借助项目说明和SQL脚本可以快速初始化数据库并运行项目在此基础上继续扩展功能也可用于答辩展示或期末验收。1. 设备维修管理系统是什么JavaWeb 课设/毕设里最稳妥的选型如果你正在为 JavaWeb 课程设计或毕业设计挑题目这份带源码和项目说明的“设备维修管理系统”几乎是绕不开的选项。它用原生 servlet 处理请求、用 JDBC 操作 MySQL 数据库没有 Spring 那套依赖注入没有 MyBatis 的 XML 映射一切都是“裸写”的 Java Web 代码。这种技术栈的好处是整个请求生命周期、数据库连接开关、事务边界全部暴露在你面前答辩时老师问“这一行是在干什么”你答得上项目就稳了。它还自带一份项目说明文档能直接改写成课程设计报告或毕设论文的设计部分省掉从零攒文档的时间。适合的人群很明确正在做 JavaWeb 课程设计的学生、需要快速交付一个完整案例的初学者以及想补习原生 Servlet 和 JDBC 底层原理的在职开发。这篇笔记就是按“怎么跑起来、怎么连库、怎么调参、怎么应对答辩追问”的顺序来写的照着做能把这套源码变成你自己的东西。设备维修管理系统的核心业务并不复杂设备信息登记、维修工单派发、维修记录归档、备件出入库、用户权限区分。它之所以适合做课设是因为业务表之间有清晰的主外键关系和状态流转能自然引出事务处理、级联查询、权限拦截这些高频考点。整个项目跑起来后你看到的是登录页、设备列表、工单列表、维修记录表单这几张网页但背后是几十个 Servlet 类和一组 DAO 类在协作。先把这个骨架认清楚后面每一步操作才能落地。2. 原生 Servlet JDBC 的内核拆解模型、视图、控制器的分工与连接池选型拿到 zip 解压后先别急着启动花二十分钟把目录结构读一遍。这类 JavaWeb 项目的包布局通常是这样src下按entity、dao、service、servlet、util分包web目录下放着jsp、css、jsWEB-INF/lib里是 MySQL 驱动 jar 包。也许在你的版本里包名略有出入比如把entity写成bean或pojo把servlet写成controller但分层逻辑万变不离其宗。下面按我的经验把这套结构的职责边界说清楚。2.1 三层架构在“裸 Servlet”里的真实位置所谓三层架构在这个项目里不是抽象的而是能精确映射到代码包上的表现层就是 Web 目录下的 JSP 页面加 Servlet。JSP 负责展示Servlet 负责任务分发两者通过request.getRequestDispatcher(xxx.jsp).forward(...)协作。控制层是 Servlet 类它们继承HttpServlet重写doGet和doPost比如/equipment/list、/workorder/add、/workorder/handle这些路径都对应具体的 Servlet。业务层是service包下的类比如EquipmentService、WorkOrderService每个方法对应一个完整业务动作例如“创建设备维修工单并扣减备件库存”。数据层是dao包里面全是 JDBC 操作一个方法对应一条或一组 SQL。这套分层的关键是依赖方向Servlet 调 ServiceService 调 DAODAO 用 JDBC 操作数据库。如果解压后看到某个 Servlet 直接写了 JDBC 代码贴 Connection、写 PreparedStatement也不用觉得奇怪很多课设为了省事会把 Service 层省略。我的建议是读代码时把 jsp 文件当作视图来对待注意力集中到 Servlet 的doPost方法里那一串request.getParameter和转发语句上这就是整个系统的控制逻辑。2.2 JDBC 在这个项目里为什么比 MyBatis 更能撑起“项目说明”JDBC 全称 Java Database Connectivity是 Java 操作数据库的底层规范。这个项目没有引入连接池所以在 DAO 里你会反复看到一段固定模板Class.forName(com.mysql.jdbc.Driver)加载驱动DriverManager.getConnection(url, user, password)建立连接PreparedStatement执行 SQL最后在finally块里关闭rs、stmt、conn三个对象。这段代码写着麻烦但每一行的作用都能在项目说明里写成一段文字这是它最大的价值。我一般会建议课设选手不要只把 JDBC 当“麻烦的旧东西”而要把连接获取、参数绑定、事务控制这三个点当成必讲内容参数绑定用PreparedStatement而不是Statement关键原因是防 SQL 注入和预编译复用。比如查询某台设备的维修记录正确写法是pstmt.setInt(1, equipmentId)如果改成字符串拼接答辩时老师一句“怎么防注入”就会卡住。事务控制当“保存工单”和“更新设备状态”需要同时成功或同时失败时需要先conn.setAutoCommit(false)最后conn.commit()异常时conn.rollback()。项目说明文档里如果能画这个流程图整个代码的含金量立刻高一个档次。2.3 设备维修管理系统的数据库表设计与外键关系创建数据库时表名一般用equipment、work_order、maintenance_record、spare_part、user这些表的主键大多是自增整型id。外键关系按业务语义连接维修工单通过equipment_id关联设备表通过handler_id关联用户表维修记录通过work_order_id关联工单表备件出库单通过spare_part_id关联备件表。常见做法是直接由equipment表的status字段表示“正常 / 维修中 / 报废”而work_order表的status表示“已提交 / 处理中 / 已完成”。查询时最核心的一条 SQL 是“查询未完成的工单并带出设备名称和维修人姓名”这要求把设备表和用户表做两次内连接SELECT wo.id, wo.create_time, e.name AS equipment_name, u.real_name AS handler_name FROM work_order wo JOIN equipment e ON wo.equipment_id e.id LEFT JOIN user u ON wo.handler_id u.id WHERE wo.status IN (已提交, 处理中) ORDER BY wo.create_time DESC;这段 SQL 如果放在项目说明的功能模块描述里再配一段 DAO 代码评分老师一眼就能看出你对表关系是掌握的。注意LEFT JOIN用户表而不是INNER JOIN原因是工单有可能还没派给维修师傅此时handler_id是 NULL内连接会把这个工单丢掉业务上就“丢单”了。这是真实项目里非常典型的细节坑。2.4 为什么“零依赖”反而适合拿来当学习项目这个项目没有任何框架依赖导致很多人会认为它“老土”。但从答辩和学习效果看零依赖是优点。当你从头到尾亲手连接一次数据库、亲手写一个 Servlet 转发、亲手跟踪一次请求从 URL 到 JSP 的完整过程你对 JavaWeb 的的理解会比直接跑一个 Spring Boot 管理系统要深得多。Spring Boot 已经帮你把 Tomcat、数据源、事务管理全部做好你看到的只是注解底层细节全是黑匣子。设备维修管理系统这套源码Node 里没有黑匣子所有包都是打开的状态每个类都能被阅读每个方法都能被断点跟踪——这正是“源码项目说明”这个 zip 最值钱的地方。看代码时有两个点特别值得留意一是 web.xml 或WebServlet注解中的 URL 映射这决定了每个页面请求由哪个 Servlet 处理二是字符编码过滤器如果系统里没写CharacterEncodingFilter你提交中文表单时大概率会出现乱码。这两个点分别对应着部署和编码两处坑后面章节会展开。3. 把 zip 变成能跑的 JavaWeb 项目IDEA 导入、Tomcat 部署与启动全流程拿到 zip 后第一件事不是读代码而是把它在自己的机器上跑起来。这一节的操作环境默认是 IntelliJ IDEA Tomcat 8.5/9.x JDK 1.8这是 JavaWeb 课程设计最常见的搭配。版本选择上有一条血泪经验用 Tomcat 10 跑原生 Servlet 课设往往会报包名错误因为 Tomcat 10 把javax.servlet换成了jakarta.servlet老项目驱动不了。所以操作系统校验时先确认 Tomcat 版本是 8.5 或 9。3.1 导入工程的三种方式和必须勾选的选项先解压 zip确认目录内部是否带.idea文件夹。带.idea说明是 IDEA 工程直接Open选中目录即可如果只有.iml文件或什么 IDEA 配置文件都没有就选Import Project或者New - Project from Existing Sources。导入向导里有一个关键选项“Import project from external model”选 Eclipse 或 Maven 时要按源码实际使用的构建工具判断。这个项目多数情况是普通 JavaWeb 工程没有 pom.xml所以选Create project from existing sources就行。导入后看到“Project Structure”弹窗不要急着关需要检查四件事Project SDK 是否为 1.8Language Level 是否为 8Modules 里src目录是否被标记为 Sourcesweb 目录是否被标记为 Web Resources Directory。很多人跑不起来不是因为代码有问题而是src没被识别成源码根目录导致编译后的 class 文件根本没进入发布包。# 如果项目里没有 .idea也可以在命令行用以下方式先看目录结构 unzip 设备维修管理系统源码项目说明JavaWeb项目使用原生servlet和JDBC.zip -d equipment-system find equipment-system -type f -name *.java | head -30上面两条命令的作用是解压并把 Java 源码文件列出来确认源码确实存在。如果你在 Windows 上用图形化解压也可以跳过命令行直接看解压后是不是同时有src和web两个一级目录。这一步是为了在导入 IDEA 前建立对项目结构的预期避免导入一个空壳工程时还要回头排查压缩包是否完整。3.2 IDEA 里配置 Tomcat 和 Artifact 的关键参数配置 Tomcat 是这一步里最容易翻车的环节。点击Run - Edit Configurations左上角加号选Tomcat Server - Local。Application server 一栏选本地 Tomcat 安装目录JRE 选 JDK 1.8。如果此界面里的 Tomcat 选项是灰的说明 IDEA 没识别到 Tomcat 路径手动点“Configure”指定到apache-tomcat-9.x根目录即可。然后重点来了上方切到Deployment页签点加号选Artifact把项目自带的war exploded或自动生成的带:war exploded的条目加进去在下方的Application context填/equipment或者项目原来用的上下文路径。这个值决定你访问系统主页时 URL 是什么比如http://localhost:8080/equipment/login.jsp。如果 Application context 填的是/主页路径就是http://localhost:8080/login.jsp。这里必须跟代码里的跳转路径对应上否则登录成功后跳转 URL 就会 404。Tomcat 端口在Configurations里的 HTTP port 一般是 8080如果被占用改成 8081 或 8082 都行。改的时候留意8080 被占用的常见原因是你已经启动过一次 Tomcat 没关闭或者某个进程占用了端口。命令行用netstat -ano | findstr 8080Windows或lsof -i :8080mac/Linux查一下确认占用进程是不是残留的 Java 进程。3.3 发布前的最后一步把驱动 jar 放进 WEB-INF/lib这一步是新手最容易漏的。光在 IDEA 的 Project Structure 里把mysql-connector-java-x.x.x.jar添加到 Libraries 还不够运行 Tomcat 时容器加载的是WEB-INF/lib目录下的 jar而不是 IDEA 编译时用的依赖。最常见的报错是java.lang.ClassNotFoundException: com.mysql.jdbc.Driver原因就在这里。把 jar 拷到 web/WEB-INF/lib 下的操作我一般直接这样做在解压后的工程里先找一下有没有lib目录和驱动 jar如果没有从 Maven 仓库或者从你自己本地的下载目录里找到合适的驱动包复制进去。驱动版本记住一条MySQL 5.x 用mysql-connector-java-5.1.4x连接串驱动名是com.mysql.jdbc.DriverMySQL 8.x 用 8.0.x 驱动驱动名是com.mysql.cj.jdbc.Driver。选错驱动类名启动时会直接抛ClassNotFoundException这一步属于最高频事故。配置完成后点绿色运行按钮IDEA 会编译并启动 Tomcat。控制台出现Starting Servlet Engine和Server startup in xxx ms字样就代表启动成功。如果启动过程中直接报严重: 子容器启动失败多半是 web.xml 里的 servlet 类名写错、JDK 版本不匹配或者 lib 下的 jar 冲突。这类错误信息很长但真正的报错原因通常在第一条不要看最后一行。4. JDBC 连接 MySQL 的配置细节驱动、连接串与 5 个必调参数项目跑起来后第一个见到的大概率是登录页但输入账密后如果报数据库连接失败整个系统就停在原地了。这一章专门讲连接 MySQL 时那些“玄学”一样的报错到底是怎么回事。JDBC 连接串、驱动类名、用户名、密码、编码、时区、SSL这些点的优先级比业务代码高任何一个不对业务逻辑再正确也白搭。4.1 连接串参数逐个拆解useSSL、serverTimezone、characterEncodingJdbcUtil 或 DBUtil 类里的连接串通常长这样private static final String URL jdbc:mysql://localhost:3306/equipment ?useSSLfalse serverTimezoneAsia/Shanghai characterEncodingutf-8; private static final String USER root; private static final String PASSWORD 123456;三个参数的用途分别是useSSLfalse是因为本地开发没有配置 SSL 证书MySQL 8.x 默认要求 SSL 连接不关掉会报SSL connection error但注意生产环境不能照抄通信加密该开还得开serverTimezoneAsia/Shanghai是因为 MySQL 8.x 默认时区跟 JDBC 驱动所在 JVM 的时区不一致不配会报The server time zone value йʱ is unrecognized这样的乱码时区错误characterEncodingutf-8是让驱动和数据库之间用 UTF-8 传字符防止中文乱码。另外连接串里也可以加useUnicodetrue老项目中常会有它是characterEncoding的配套开关保留即可。这三个是我通过项目说明文档反查配置时最常看到也最常出问题的参数。4.2 驱动类名的两个新老版本对比驱动类名跟 jar 版本强绑定。MySQL Connector/J 5.x 的驱动类是com.mysql.jdbc.Driver8.x 的驱动类是com.mysql.cj.jdbc.Driver。如果项目说明文档里写的是旧驱动名但你因为系统限制用了新版 jar运行时必然报ClassNotFoundException。解决方式很简单优先让驱动名和 jar 版本匹配不要硬改代码。从可维护性角度选 8.0 驱动配新连接串是长期来看更稳的组合但在课设环境下“项目里原来怎么写的就用对应版本 jar”往往能少踩一个坑。默认端口也要注意MySQL 默认端口 3306但不少本机安装的 MySQL 因为之前装了多个实例实际运行在 3307 或 3308。确认端口的方式是登录 MySQL 后执行SHOW VARIABLES LIKE port;或者在连接工具里看连接参数。如果 URL 里的端口跟实际端口不一致报错是CommunicationsException: Communications link failure这种报错原因很多是 JDBC 连接里最难排查的一个后面的避坑章节会把链路拆开讲。4.3 MySQL 授权与用户权限排查 Access denied 的顺序Access denied for user rootlocalhost (using password: YES)这条错误几乎每个人都会遇到一次。出现它的原因按概率排序是连接串里的密码本身是错的连接串里的密码正确但 MySQL 用户密码不一致root 用户只允许localhost登录而连接串里用了 127.0.0.1 或远程 IP用户密码策略导致你设的简单密码不生效。排查顺序我也建议按这个顺序走先在命令行用同样的密码登录一次 MySQL如果命令行登不进去问题就在密码本身用ALTER USER rootlocalhost IDENTIFIED BY 新密码;重置再试如果命令行能进但程序报错看 URL 里的 host 写的是localhost还是127.0.0.1在 MySQL 里SELECT user, host FROM mysql.user;看 root 的授权 host 范围。此时我一般会在项目说明里补一句话“本系统默认连接本地 MySQL 数据库用户名 root密码改为你自己的配置”。这句话听起来没什么含金量但能避免你把原始密码写死在连接串里被人看到同时也能提示使用者修改。4.4 JDBC 操作数据库的完整示例以设备列表查询为例连接配置好以后一个典型的“查询所有设备”的 DAO 方法应该长这样public ListEquipment findAll() { ListEquipment list new ArrayList(); String sql SELECT id, name, model, status, purchase_date FROM equipment ORDER BY id; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql); ResultSet rs ps.executeQuery()) { while (rs.next()) { Equipment e new Equipment(); e.setId(rs.getInt(id)); e.setName(rs.getString(name)); e.setModel(rs.getString(model)); e.setStatus(rs.getString(status)); e.setPurchaseDate(rs.getDate(purchase_date)); list.add(e); } } catch (SQLException e) { throw new RuntimeException(查询设备列表失败, e); } }代码里用的是 try-with-resources它会在代码块结束时自动关闭conn、ps、rs比传统手写finally更优雅也更安全。如果你在源码里看到的是手写finally关闭也别觉得不对只是风格差异。要注意的是setDate和getDate是java.sql.Date如果实体类用的是java.util.Date两者之间需要做一次转换否则取出的时间会缺少时分秒。这是 JDBC 编程里面最容易被忽略的日期类型陷阱之一很多人的设备购买时间查询出来是yyyy-MM-dd维修时间却带时分秒就是这里混用了两种 Date。4.5 连接串参数修改后的验证方式连接配置常见做法是把 db.properties 文件中的值修改后重启 Tomcat。为验证修改是否生效在浏览器访问一个跟数据库无关的静态页面是测不出效果的需要真正触发一条查询 SQL。最简单的验证方式是直接访问系统首页看设备列表或工单列表是否加载出来如果配错了连接串Tomcat 控制台会在你第一次发请求时抛出异常而不是在启动时报错。这是因为 JDBC 默认懒加载连接第一次执行 SQL 时才会尝试建立物理连接。理解了这一点就能解释很多“项目明明启动成功但一点页面就报错”的现象。看到这里你也就明白JavaWeb 项目里最折磨人的坑多半不在代码逻辑而在配置文件和环境。下一章就把这些坑整理成一份可以直接对照的清单。5. 避坑8 个最常见的 Servlet JDBC 翻车现场与排查方法这一章写的都是我在类似 JavaWeb 项目里看到的真实踩坑记录现象、原因、解决方式都尽量按“看得懂、用得上”的标准写。如果你正在调试这套源码建议把这些条目当作排查手册按现象对号入座。5.1 页面能打开但所有涉及数据库的页面都报“HTTP Status 500”现象登录页能正常打开输入账号密码后页面变成 500日志打了一长串异常。原因多半是数据库连不上或 SQL 语句出错但这两种情况的表象完全一样。解决先看 Tomcat 控制台的第一行异常类型。Communications link failure说明网络或 MySQL 服务没起来用命令行登录一次 MySQL 验证SQL syntax error说明 SQL 写错把 SQL 语句复制到 Navicat 或命令行执行一次看报错位置。这里的常见误区是看日志只看底部实际上Caused by那几行才是有价值的信息。5.2 设备列表加载不出来报 ClassNotFoundException: com.mysql.jdbc.Driver现象Tomcat 启动正常但一访问和设备列表有关的页面就抛驱动找不到。原因刚才 3.3 节说的 jar 未拷贝到WEB-INF/lib。很多人的 IDEA 里 Libraries 能看到驱动 jar但WEB-INF/lib下没有而 Tomcat 只看后者。解决把驱动 jar 复制到web/WEB-INF/lib/下重新编译重启。如果复制后发现还是报错关掉 Tomcat清空out或target目录里旧的发布内容再重启避免 IDE 缓存里带着旧的 class 文件。5.3 MySQL 报了“The server time zone value”异常页面全挂现象首次请求数据库时报时区异常错误信息里时区名是乱码。原因驱动版本是 8.x而连接串没有serverTimezone参数。解决在连接串里追加serverTimezoneAsia/Shanghai。这里补充一个容易被忽略的点如果这台机器的操作系统时区不是中国标准时间更好的是把它改成一个固定值Asia/Shanghai一般是最稳妥的。如果追加完重启后仍报同样错误检查是不是 Tomcat 没有真正重启IDEA 有时候只重新部署了 Artifact但 JVM 还保留着旧连接参数。5.4 中文数据在页面显示成“??”或乱码现象数据库表里能看到中文但页面显示问号或者页面提交中文落库后变“??”。原因两个环节里有一个编码断了——页面提交时请求编码不是 UTF-8或者数据库连接串没指定字符集或者数据库表本身是 latin1。严格按照这个顺序排查先看连接串有没有characterEncodingutf-8再看 JSP 页面顶部有没有pageEncodingUTF-8最后看数据库表的CHARSET是不是utf8mb4不是就ALTER TABLE equipment CONVERT TO CHARACTER SET utf8mb4;。多数乱码都是因为三处编码缺一处补齐就恢复。如果项目里没有编码过滤器最规范的解决办法是写一个CharacterEncodingFilter在doFilter里强制设置request.setCharacterEncoding(UTF-8)再放行后续请求。5.5 登录成功跳转到首页时 404但地址栏的 URL 看着没问题现象登录验证通过后response.sendRedirect(/detail.jsp)或 forward 到某个页面时 404。原因Application context 和重定向路径不匹配。如果你的 context 路径是/equipment那么sendRedirect(/equipment/list.jsp)才对直接写/list.jsp会跑到根路径下找文件。解决全局搜索代码里的跳转路径把所有写死的 URL 和你设定的 Application context 对照一遍。这里有一个通用经验Servlet 里 forward 用相对路径request.getRequestDispatcher(list.jsp)通常是安全的而sendRedirect建议用带 context 的绝对路径。遇到 404 又路径看着没问题的时候打开地址栏手动加/equipment再访问一次能快速确认问题出在跳转配置还是页面文件缺失。5.6 PreparedStatement 参数占位符从 1 开始容易越界现象代码运行到pstmt.setString(1, xxx)时抛Parameter index out of range (1 number of parameters...)。原因SQL 中写的是?但实际 SQL 语句里?的数量与调用 setString 的次数不一致。解决把 SQL 语句从代码里复制出来数一遍?个数如果是动态拼接 SQL比如带了if判断再拼条件那?的数量是动态的建议把整条 SQL 在控制台打印出来人工核对。这个坑在工单查询这种支持多种筛选条件的模块里最常出现因为筛选条件变多时漏掉一个setXxx调用很难一眼发现。5.7 同一时刻发起两个请求总是有一个卡住现象点击“保存工单”时页面长时间不响应但单个请求时又正常。原因没有使用数据库连接池每次请求都新建物理连接而 MySQL 默认最大连接数在 151当并发稍高时两个线程同时获取连接其中一个会等connect timeout。解决课设阶段最简单的方式是接受这个限制告诉老师“这是原生 JDBC 连接适合教学场景生产环境应引入连接池”。如果想让系统在演示时稳定一点可以在DBUtil里使用单例连接对象但这不是最佳实践只是演示救急。真实的解决路径是引入 Druid 或 HikariCP 连接池把这部分写进项目说明的“未来改进”章节会非常加分。5.8 页面报了“Cannot call getConnection() before Tomcat initialization completed”现象Tomcat 启动过程中某个 Servlet 的init方法里尝试获取数据库连接结果抛出上述错误。原因数据库连接初始化时机太早或者DBUtil的静态代码块里在 Tomcat 还没完成初始化时就去加载驱动并连库。解决把数据库连接获取放到第一次请求时懒加载或者把连接池初始化放在监听器ServletContextListener的contextInitialized方法里。这里最常见的情况是DBUtil用了静态初始化块里面执行了DriverManager.getConnection一旦 MySQL 没起来整个 Tomcat 启动直接失败。修复方式是静态块里只加载驱动类连接放到getConnection()方法内部每次实时获取这样 MySQL 的故障可以被延后到请求时暴露而不是启动时。注意延时暴露只是权宜生产环境不能这么干但课设场景下这种改动小、解释起来也合理。6. 把项目说明写厚数据字典、核心流程与 3 个答辩追问预案zip 里的项目说明是这套源码容易被低估的部分。设备维修管理系统的代码量不大但项目说明写得好不好直接影响课设评分甚至比代码本身还关键。据我做课设的经验能拿到高分的项目说明通常包含三类内容一张完整的数据字典表、一张核心业务流程图用文字描述清楚状态流转也可以、以及对“为什么这样设计”的解释。下面把这三类的写法说透。数据字典表要按“表名、字段名、类型、是否主键、是否外键、说明”的格式列出。比如work_order表的核心字段可以这样写id主键、equipment_id外键关联设备表、handler_id外键关联用户表、status表示工单当前状态、create_time记录提交时间。这张表是答辩时最有说服力的材料“你设计系统时考虑了哪些数据”全靠它体现。核心流程写“新增维修工单”的完整链路前端提交工单表单 →WorkOrderAddServlet获取参数 →WorkOrderService.add()开启事务 → 插入工单记录 → 更新设备状态为“维修中” → 提交事务 → 跳转工单列表页。这个流程写清楚后事务和状态流转两个知识点都被你覆盖到了。最后准备三个答辩追问预案。第一问“你的数据库没有外键约束怎么做数据完整性”回答方向应用程序层面控制的service层里手动校验外键 ID 是否存在生产环境可以再加外键约束。第二问“原生 JDBC 有什么缺点你怎么改进”回答方向连接每次都要创建、性能低引入连接池SQL 和 Java 代码耦合引入 MyBatis 可以解决。第三问“如果维修设备时库存不够你怎么处理”回答方向在事务里先查备件库存再决定是否允许出库库存不足就抛出业务异常并提示这又回到事务边界的知识点上。我当年做这套系统时最深的教训是把项目说明拖到答辩前一晚才动手结果被问“备件表为什么没有外键”时被问住了。后来才明白课设系统的代码只能证明你会写程序项目说明才是证明你“懂设计”的地方。这份 zip 给你提供的不只是能跑的源码更是一套可以复用的说明文档骨架你只需要把表结构、流程和你的真实配置替换进去就已经领先大多数同学了。希望你少走我走过的弯路把这份源码跑通、讲透带着它稳稳通过答辩。本文还有配套的精品资源点击获取