
简介《基于Java的宿舍管理系统设计与实现》是本科毕业设计论文文档面向计算机相关专业学生及需要参考Java Web管理项目的开发者。系统以MySQL数据库为存储后端、Eclipse为开发环境覆盖宿舍信息、宿舍评分、学生评分、来访登记、维修登记、班级管理、学生管理等模块着力解决传统手工记录繁琐、查询困难、易出错等问题对提升宿舍管理效率和规范化程度有直接价值。文档包含中英文摘要、目录、绪论、系统设计、数据库设计、功能实现与测试维护等章节完整呈现从需求分析到项目交付的开发脉络有助于理解模块划分、数据库表设计思路与论文写作规范。资源共1个docx文件大小1.09MB已有56人学习内容组织清晰、便于按章节查阅适合用于论文撰写、模块设计参考或JavaMySQL项目复现。1. 基于 java 的宿舍管理系统设计与实现这个课设/毕设选题到底要交什么“基于 java 的宿舍管理系统设计与实现”这个标题是高校课程设计和毕业设计里出现频率极高的一个固定命题。它要你交付的不只是一段能跑的代码而是一套完整的「设计思路 数据库建模 功能实现 文档说明」这也是为什么标题后缀带 .docx——最终答辩时代码和文档缺一不可。系统本身不复杂核心无非是学生信息维护、宿舍分配与调换、退宿登记、报修处理和简单的统计查询但正因为业务边界清晰它非常适合用来检验 Java 基础、JDBC、Swing/JavaFX 界面编程和数据库设计这些硬技能。适合谁正在做课程设计、准备毕业设计或者想用一个小而完整的项目巩固 Java 全流程的初学者。别指望这里有什么高并发和微服务它考验的是你把一个真实业务闭环做扎实的能力。2. 技术选型与设计边界为什么是 Swing JDBC MySQL 而不是别的组合2.1 界面层选 Swing 还是 JavaFX从课程设计和答辩场景来定很多人在选题后第一件事就问界面用 Swing 还是 JavaFX。我的建议很直接默认 Swing除非导师明确要求 JavaFX。理由不是技术上的优劣而是答辩现场的匹配度。Swing 是 JDK 自带的 GUI 工具包不需要额外引入运行时环境打包成一个 jar 就能在装了 JDK 的机器上跑。大多数课程设计的验收环境就是机房电脑老师对 JFrame、JTable、JPanel 这一套非常熟悉提问时问来问去也就是布局管理器和事件监听这一层。JavaFX 界面确实好看控件也现代但它需要单独的运行时模块JDK 8 之后还要配 JavaFX 依赖如果项目是用 JDK 11 以上开发的光解决运行时缺模块的问题就可能劝退一批人。从答辩展示效果看Swing 也够用。宿舍管理系统的界面无外乎登录窗口、主窗体、学生信息表格、宿舍分配表单、报修登记面板。用 JTable 展示学生列表用 JComboBox 选择宿舍楼栋和床位用 JTabbedPane 区分功能模块效果足够清爽。不要为了炫技引入 UI 框架这个项目的核心考察点不在这里。还有一个界面层的隐藏考量打印和导出。课程设计经常要求把宿舍名单导出成 Word 或 Excel 文档Swing 配合 Apache POI 做导出非常成熟网上资料多、踩坑记录也全。如果你选 JavaFX导出逻辑本身不变但界面线程模型和 Swing 不同出问题排查起来更费劲。我见过不少同学在 JavaFX 的 Platform.runLater 里卡了一整天最后换回 Swing 半小时搞定。2.2 数据层选 JDBC 还是 ORM 框架手写 SQL 反而更好过答辩数据层也是一道分岔路传统 JDBC、MyBatis 还是 JPA对这个项目我强烈建议手写 JDBC最多用一个轻量工具类封装连接和释放过程。原因在于这类设计题目有明确的「设计文档」要求。你的《设计与实现》文档里必须包含系统总体设计、数据库设计、模块设计这些章节。用 JDBC 手写 SQL你能清清楚楚地逐条解释这五张表怎么建、外键怎么关联、查询为什么这么写。答辩老师问“宿舍剩余床位怎么查”你直接说“一条 SQLSELECT capacity - COUNT(*) FROM dormitory LEFT JOIN student GROUP BY dorm_id”逻辑透明无懈可击。用 MyBatis 当然也行但老师下一个问题就会追到 XML 映射文件、动态 SQL、一级缓存二级缓存上。这些对于课程设计来说既不是重点你也不见得能讲透。如果碰上一个不懂 MyBatis 的老师他会觉得你在绕弯子反而扣分。JPA/Hibernate 更不建议。它的自动建表、懒加载、级联操作对新手来说是个黑匣子一旦遇到数据不一致你连问题出在哪都不知道。而且实体类上的注解一大堆答辩时被问“这里为什么用 ManyToOne 而不是 OneToMany”你能答得清吗手写 JDBC 的另一个好处是 SQL 能力肉眼可见地提升这对后续面试也更有实际帮助。2.3 三层架构与模块划分包结构、分层边界和关键文件无论用哪种界面技术和数据层方案系统的代码结构必须分层。这是《设计与实现》文档里“系统总体设计”章节的核心内容也是答辩老师一定会看的地方。我建议按四层划分ui 层界面与交互、service 层业务逻辑、dao 层数据库访问、entity 层实体类。再加上一个 util 包放数据库连接工具类和公共校验方法。典型包结构如下entityStudent、Dormitory、Admin、RepairOrder、DormitoryRecorddaoStudentDao、DormitoryDao、AdminDao、RepairOrderDaoserviceStudentService、DormitoryService、RepairServiceuiLoginFrame、MainFrame、StudentPanel、DormitoryPanel、RepairPanelutilDBUtil、StringUtil、TableUtil分层的边界要清楚ui 层只负责接收用户输入和展示结果不写 SQLdao 层只做增删改查不拼业务service 层做逻辑判断比如分配宿舍时先查宿舍类型是否匹配然后调用 dao 落地。这样写的直接好处是如果中途想把 Swing 界面换成控制台测试service 层和 dao 层可以原封不动地复用。2.4 运行环境与依赖的最小配置清单我一般会把项目运行环境固定为一套稳妥的配置也建议读者按这个来减少环境差异带来的玄学问题组件推荐版本说明JDK1.8 或 8u202自带 Swing环境变量配好后无需额外依赖MySQL5.7 或 8.05.7 对 JDBC 驱动兼容性最稳8.0 需用新版驱动mysql-connector-java5.1.49对应 MySQL 5.7/ 8.0.33对应 MySQL 8.0驱动类名不同详见避坑章节IDEEclipse 或 IntelliJ IDEA直接用 IDE 运行省去打包步骤操作系统Windows 10/11 即可注意 MySQL 服务需要手动启动这套组合的好处是你拿到任何一台新电脑都能在半小时内把环境搭到可运行状态。JDK 8 和 MySQL 5.7 的组合经过大量课程设计验证是翻车率最低的搭配。3. 数据库设计与实现把宿舍业务拆成五张表附建表 SQL 和初始化数据3.1 实体识别从业务流程反推数据表数据库设计是整个系统的地基。宿舍管理系统的业务流程并不复杂但很多新手一上来就建十几张表最后自己都绕晕了。我建议从最常见的流程反推学生入学后要分配宿舍住进去之后可能报修毕业时要退宿期间可能产生水电费记录。围绕这条主线最少需要五张表管理员表admin、学生表student、宿舍表dormitory、入住记录表dormitory_record、报修表repair_order。有的方案会把水电费单独建表但课程设计阶段我更推荐把当月的宿舍费用作为一个字段放在 dormitory 表里或者用一张简单的 charge_record 记录。五张表的好处是实体关系清晰ER 图画起来整齐文档好写答辩好讲。以下是每个实体的核心职责admin 表存系统登录账号student 表存学号、姓名、性别、班级、联系电话以及当前宿舍 IDdormitory 表存楼栋、房间号、容量、性别属性男/女、当前已住人数和宿舍状态dormitory_record 表记录每次入住和退宿的操作轨迹包括入住时间和退宿时间repair_order 表登记报修的宿舍、报修内容、状态和完成时间。3.2 建表 SQL字段设计与主外键关系下面是一份可以直接执行的建表脚本。注意我使用了 utf8mb4 字符集避免中文乱码问题这是这类系统最常见的翻车点之一。-- 创建数据库指定字符集 CREATE DATABASE IF NOT EXISTS dormitory_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE dormitory_system; -- 管理员表 CREATE TABLE admin ( admin_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 管理员ID, username VARCHAR(50) NOT NULL UNIQUE COMMENT 登录用户名, password VARCHAR(64) NOT NULL COMMENT 登录密码建议MD5加密存储, real_name VARCHAR(50) COMMENT 真实姓名, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间 ) ENGINEInnoDB COMMENT 系统管理员表; -- 宿舍表 CREATE TABLE dormitory ( dorm_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 宿舍ID, building VARCHAR(20) NOT NULL COMMENT 楼栋号, room_no VARCHAR(20) NOT NULL COMMENT 房间号, capacity INT NOT NULL COMMENT 床位容量, gender ENUM(男,女) NOT NULL COMMENT 宿舍性别属性, current_count INT DEFAULT 0 COMMENT 当前已住人数, status ENUM(正常,维修中) DEFAULT 正常 COMMENT 宿舍状态, UNIQUE KEY uk_building_room (building, room_no) ) ENGINEInnoDB COMMENT 宿舍信息表; -- 学生表 CREATE TABLE student ( student_id VARCHAR(20) PRIMARY KEY COMMENT 学号, name VARCHAR(50) NOT NULL COMMENT 姓名, gender ENUM(男,女) NOT NULL COMMENT 性别, class_name VARCHAR(50) COMMENT 班级, phone VARCHAR(20) COMMENT 联系电话, dorm_id INT COMMENT 当前宿舍ID空表示未分配, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (dorm_id) REFERENCES dormitory(dorm_id) ) ENGINEInnoDB COMMENT 学生信息表; -- 入住记录表 CREATE TABLE dormitory_record ( record_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 记录ID, student_id VARCHAR(20) NOT NULL COMMENT 学号, dorm_id INT NOT NULL COMMENT 宿舍ID, action ENUM(入住,退宿) NOT NULL COMMENT 操作类型, operate_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 操作时间, FOREIGN KEY (student_id) REFERENCES student(student_id), FOREIGN KEY (dorm_id) REFERENCES dormitory(dorm_id) ) ENGINEInnoDB COMMENT 入住退宿记录表; -- 报修表 CREATE TABLE repair_order ( repair_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 报修ID, dorm_id INT NOT NULL COMMENT 宿舍ID, student_id VARCHAR(20) COMMENT 报修人学号, description VARCHAR(500) NOT NULL COMMENT 报修内容, status ENUM(待处理,处理中,已完成) DEFAULT 待处理 COMMENT 报修状态, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 报修时间, finish_time DATETIME COMMENT 完成时间, FOREIGN KEY (dorm_id) REFERENCES dormitory(dorm_id), FOREIGN KEY (student_id) REFERENCES student(student_id) ) ENGINEInnoDB COMMENT 报修记录表;这段 SQL 里有几个设计决策需要说明。student 表里冗余了 dorm_id 字段再加一张 dormitory_record 表是否重复不重复。student 表里的 dorm_id 是学生当前状态的快照用于快速查询“某人现在住在哪”dormitory_record 表则是一个完整历史轨迹。如果只保留记录表查询当前入住状态就要做子查询如果只保留字段就无法追溯退宿历史。两者配合才是完整的宿舍业务闭环。dormitory 表里冗余了 current_count 字段。这是有意为之因为“查一下哪几间宿舍还没住满”是一个极高频操作直接查 current_count capacity 就能完成不需要每次 COUNT 全表关联。当然每次分配或退宿时都需要同步维护这个字段这一点的注意事项会在避坑章节里讲到。3.3 初始化数据让系统开箱就能演示空数据库没法演示所以必须准备初始化数据。管理员账号是必须的宿舍数据至少要有男生楼和女生楼各一栋每栋若干房间。下面是初始化脚本的节选-- 初始化管理员账号密码统一为 admin123MD5加密后存储 INSERT INTO admin (username, password, real_name) VALUES (admin, 21232f297a57a5a743894a0e4a801fc3, 系统管理员); -- 初始化宿舍数据1号楼为男生宿舍2号楼为女生宿舍 INSERT INTO dormitory (building, room_no, capacity, gender, current_count, status) VALUES (1号楼, 101, 4, 男, 0, 正常), (1号楼, 102, 4, 男, 0, 正常), (1号楼, 103, 6, 男, 0, 正常), (2号楼, 201, 4, 女, 0, 正常), (2号楼, 202, 4, 女, 0, 正常); -- 初始化几名学生先不分配宿舍 INSERT INTO student (student_id, name, gender, class_name, phone, dorm_id) VALUES (2021001, 张三, 男, 计科2101, 13800138001, NULL), (2021002, 李四, 男, 计科2101, 13800138002, NULL), (2021003, 王五, 女, 软工2101, 13800138003, NULL);注意密码字段用的是 MD5 加密后的值这是课程设计里常见做法。虽然 MD5 从安全角度已经过时但对于课设演示和学生项目来说做到“不存明文密码”这一条已经比很多入门作业强了。如果你想让项目看着更专业可以用 SHA-256 替换Java 标准库里的 MessageDigest 就能实现不需要额外依赖。3.4 数据库设计的三个自查点建完表之后我会按下面三个问题自查一遍这也是答辩时老师大概率会问的第一删除学生时如果该学生有报修记录怎么办这涉及外键策略。我建议在业务层面处理退宿前先检查 repair_order 里有没有未完成记录有则提示“该生有未完成的报修不能退宿”。这也体现了 service 层做业务判断的价值。第二宿舍的性别属性和已住人数如何保持一致答案是唯一入口原则分配宿舍只走一个 service 方法这个方法里同时完成三件事——写 dormitory_record 记录、更新 student 的 dorm_id、把 dormitory 的 current_count 加一。三件事在一个方法里要么全成功要么全失败事务控制避免数据不一致。第三查询宿舍剩余床位用哪种 SQL这里贴一下最常用的语句它在宿舍分配功能里要反复用到SELECT d.* FROM dormitory d WHERE d.gender 男 AND d.current_count d.capacity AND d.status 正常 ORDER BY d.building, d.room_no;这条 SQL 查出的就是“当前符合性别条件、有空床、可正常使用”的宿舍列表供界面下拉框填充。注意 status 字段的过滤很容易漏漏掉之后就会把维修中的宿舍也分配出去属于典型的边界条件错误。4. 核心功能实现从登录到宿舍分配、报修登记的 Java 代码与参数说明4.1 数据库连接工具类JDBC 参数逐个讲清楚有了表结构接下来就是 Java 代码。整个系统里复用频率最高的一定是数据库连接工具类 DBUtil。它负责加载驱动、建立连接、释放资源。直接把它写成一个静态工具所有 DAO 类都通过它拿连接。package util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class DBUtil { // 驱动类名MySQL 5.x 用的是 com.mysql.jdbc.Driver // 如果换成 MySQL 8.x必须改为 com.mysql.cj.jdbc.Driver private static final String DRIVER com.mysql.jdbc.Driver; // URL 中 useSSLfalse 避免本地连接时 SSL 告警 // characterEncodingutf8 保证中文字符正确存取 private static final String URL jdbc:mysql://localhost:3306/dormitory_system?useSSLfalsecharacterEncodingutf8serverTimezoneAsia/Shanghai; private static final String USER root; private static final String PASSWORD 123456; static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); throw new ExceptionInInitializerError(MySQL驱动加载失败请检查jar包); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } // 释放资源先释放ResultSet再Statement最后Connection public static void close(Connection conn, Statement stmt, ResultSet rs) { if (rs ! null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stmt ! null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn ! null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }这段代码有几个参数需要特别说明。URL 里我加了 serverTimezoneAsia/Shanghai如果你用的是 MySQL 8.0 且没有设置时区参数连接时大概率会抛异常报错信息里会提示服务器时区值无法识别。useSSLfalse 是关闭 SSL 加密连接本地开发不需要加了反而可能出现证书告警。characterEncodingutf8 解决的是中文写入乱码问题这里只解决客户端到服务端的编码数据库本身的字符集还要靠建库时指定 utf8mb4两层都对了中文才能彻底不乱。4.2 登录功能界面、事件监听与数据库校验登录是系统的入口。界面部分用一个 JFrame 放用户名输入框、密码输入框和登录按钮点击按钮后从数据库校验账号密码。这里的关键是 dao 层只写查询逻辑service 层只做密码比对判断ui 层只弹提示框package dao; import entity.Admin; import util.DBUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; public class AdminDao { public Admin findByUsername(String username) { String sql SELECT admin_id, username, password, real_name FROM admin WHERE username ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { // 参数索引从1开始? 占位符不能直接拼接字符串防止SQL注入 ps.setString(1, username); try (ResultSet rs ps.executeQuery()) { if (rs.next()) { Admin admin new Admin(); admin.setAdminId(rs.getInt(admin_id)); admin.setUsername(rs.getString(username)); admin.setPassword(rs.getString(password)); admin.setRealName(rs.getString(real_name)); return admin; } } } catch (Exception e) { e.printStackTrace(); } return null; } }service 层负责判断逻辑如果查到的 admin 不为空且密码匹配返回 true否则提示“用户名或密码错误”。注意这里我用 PreparedStatement 而不是 Statement这是为了防止 SQL 注入的基本功。第一版系统里经常有人写字符串拼接的查询看起来省事但一旦用户名里出现单引号就会报错而且本身就是安全隐患。登录密码的比对逻辑我这里演示的是明文比对。如果你按第三章节存储了 MD5 后的密码service 层比对的是 MD5 后的值和数据库值是否相等这一步别忘了。package service; import dao.AdminDao; import entity.Admin; import util.MD5Util; public class AdminService { private AdminDao adminDao new AdminDao(); public boolean login(String username, String rawPassword) { // 参数校验用户名和密码都不能为空 if (username null || username.trim().isEmpty() || rawPassword null || rawPassword.isEmpty()) { return false; } Admin admin adminDao.findByUsername(username.trim()); if (admin null) { return false; } // 用加密后的密码做比对 String md5Password MD5Util.md5(rawPassword); return md5Password.equals(admin.getPassword()); } }这个 login 方法里有两个边界处理值得注意一是空值校验用户名 trim 后再去查库避免用户误输入空格导致查不到数据二是密码用加密后再比对数据库里如果存的是密文而你拿去和明文比永远比对不上。这两个细节都是答辩时可能被追问的点。4.3 宿舍分配的核心逻辑性别匹配、容量检查和事务一致性宿舍分配是整个系统里最重要的业务功能也是最容易写出逻辑漏洞的地方。完整流程是界面选择一名未分配宿舍的学生然后选择一个符合条件的宿舍点击分配后完成三件事——写入记录表、更新学生 dorm_id、更新宿舍当前人数。public class DormitoryService { public boolean assignDormitory(String studentId, int dormId) { // 第一步查询学生信息和宿舍信息用于业务判断 Student student studentDao.findById(studentId); Dormitory dorm dormitoryDao.findById(dormId); // 第二步业务校验所有不满足条件的情况都提前返回 if (student null || dorm null) { return false; } if (student.getDormId() ! null) { // 该学生已有宿舍不能重复分配 throw new RuntimeException(该学生已分配宿舍请先退宿再分配); } if (!student.getGender().equals(dorm.getGender())) { // 性别不匹配比如女生分到了男生宿舍 throw new RuntimeException(学生性别与宿舍性别属性不匹配); } if (dorm.getCurrentCount() dorm.getCapacity()) { // 宿舍已满员 throw new RuntimeException(该宿舍床位已满); } if (维修中.equals(dorm.getStatus())) { // 维修中的宿舍不能分配 throw new RuntimeException(该宿舍维修中暂不可分配); } // 第三步三个更新操作在同一个事务中执行防止数据不一致 Connection conn null; try { conn DBUtil.getConnection(); // 关闭自动提交开启事务 conn.setAutoCommit(false); // 3.1 写入入住记录 recordDao.addRecord(conn, studentId, dormId, 入住); // 3.2 更新学生的宿舍ID studentDao.updateDormId(conn, studentId, dormId); // 3.3 宿舍已住人数 1 dormitoryDao.incrementCount(conn, dormId); // 全部成功才提交 conn.commit(); return true; } catch (Exception e) { // 任何一个环节出错回滚全部操作 if (conn ! null) { try { conn.rollback(); } catch (Exception ex) { ex.printStackTrace(); } } e.printStackTrace(); return false; } finally { if (conn ! null) { try { // 恢复自动提交归还连接到连接池 conn.setAutoCommit(true); conn.close(); } catch (Exception e) { e.printStackTrace(); } } } } }这段代码里最关键的设计是三件事必须在一个事务里完成。如果你分三次独立提交一旦中途出错就会出现“记录表里写了入住但学生 dorm_id 没更新”这种让数据对不上的状态。事务的开启方式是关闭连接的自动提交setAutoCommit(false)完成后手动 commit异常时 rollback最后在 finally 里恢复自动提交并关闭连接。这里还展示了业务校验的完整集合重复分配、性别不匹配、宿舍满员、宿舍维修中四条缺一不可。很多第一版系统只检查了容量结果出现男生住进女生宿舍的翻车场景。性别判断的写法是 student.getGender().equals(dorm.getGender())注意我把常量写在 equals 的前面这里的数据是变量但习惯上如果和常量比都是 男.equals(dorm.getGender()) 这种写法避免空指针。4.4 报修登记与状态流转异常输入怎么能不炸报修功能相对简单核心是登记报修内容并控制状态流转。状态从“待处理”到“处理中”到“已完成”每一步都有时间记录。public boolean createRepairOrder(RepairOrder order) { // 业务校验报修内容不能为空长度限制在500字以内 if (order.getDescription() null || order.getDescription().trim().isEmpty()) { throw new RuntimeException(报修内容不能为空); } if (order.getDescription().trim().length() 500) { throw new RuntimeException(报修内容不能超过500字); } String sql INSERT INTO repair_order (dorm_id, student_id, description, status) VALUES (?, ?, ?, 待处理); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, order.getDormId()); ps.setString(2, order.getStudentId()); ps.setString(3, order.getDescription().trim()); int rows ps.executeUpdate(); return rows 0; } catch (Exception e) { e.printStackTrace(); return false; } }这里的参数说明顺带一提executeUpdate 返回的是受影响的行数插入成功返回 1失败返回 0。通过判断返回值来判断操作是否成功是 JDBC 编程的常见套路。注意在界面层下拉框里选中的宿舍 ID 要转成 int 再传给 service如果没选就点击提交需要提前弹窗提示“请选择宿舍”。界面层的校验和 service 层的校验是两条线谁都不能省。界面层管用户友好性service 层管数据正确性。5. 避坑清单从界面卡死到 docx 文档乱码五个血泪教训5.1 驱动加载失败Class.forName 抛 ClassNotFoundException现象运行项目时报 java.lang.ClassNotFoundException: com.mysql.jdbc.Driver程序直接崩溃。原因mysql-connector-java 的 jar 包版本和驱动类名对不上。5.x 版本的驱动类名是 com.mysql.jdbc.Driver8.x 版本改成了 com.mysql.cj.jdbc.Driver。很多人直接把 MySQL 从 5.7 升级到 8.0但代码里还写的是老驱动名自然加载不到。解决要么把代码里的驱动类名改成 com.mysql.cj.jdbc.Driver要么把 jar 包降回 5.1.49 版本。我一般建议升级代码而不是降级数据库因为新版驱动对时区要求更严格顺手在 URL 里加上 serverTimezoneAsia/Shanghai一并解决。另外记得检查 jar 是否真的引入了在 IDE 的项目结构里确认依赖存在而不是只下载了没导入。5.2 Swing 界面卡死在主线程里执行了数据库查询现象点击登录按钮后整个窗口卡住不动标题栏出现“未响应”要等好几秒才恢复甚至直接假死。原因Swing 是单线程模型所有的界面刷新和事件处理都在事件分发线程EDT上执行。如果你在按钮的 ActionListener 里直接写了数据库查询比如查 5000 个学生数据来填充 JTable查询期间 EDT 被阻塞界面自然卡住。解决耗时的数据库操作放到独立线程里执行查询完成后再通过 SwingWorker 切回 EDT 更新界面。简化写法是直接用 Thread SwingUtilities.invokeLaternew Thread(() - { // 耗时查询在子线程执行 ListStudent list studentService.findAll(); // 查询结果回主界面 SwingUtilities.invokeLater(() - { fillTable(list); }); }).start();注意一个问题Swing 控件不允许在非 EDT 线程直接操作所以子线程里查完数据后必须用 SwingUtilities.invokeLater 把更新界面的动作切回去。如果直接在线程里调用 table.setModel轻则界面刷新异常重则直接抛出异常。这个坑在你数据量小的时候不明显一旦测试数据加到几千行就会暴露。5.3 中文乱码控制台正常但数据库里全是问号现象界面输入中文用户名或报修内容数据库里存进去的是“???”或者从数据库读出来再显示到界面上变成乱码。原因三层编码有一层没对齐。客户端到 MySQL 的连接编码、MySQL 数据库本身的字符集、JVM 运行时字符集只要有一处不是 UTF-8中文就会乱。解决三层分别检查。第一层建库时指定 DEFAULT CHARACTER SET utf8mb4第三章节已经这样做了第二层JDBC URL 里加 characterEncodingutf8第四章节的 DBUtil 里已体现第三层确认 IDE 的项目文件编码是 UTF-8Eclipse 里右键项目 - Properties - Resource - Text file encoding 改成 UTF-8。如果这三层都对了还是乱检查 MySQL 的配置文件 my.ini 里是否设置了 character-set-serverutf8mb4。注意 MySQL 8.0 默认字符集已经是 utf8mb4但 5.7 需要手动确认。5.4 宿舍分配逻辑漏判女生住进男生宿舍还毫不知情现象测试分配功能时把一名女生分到了男生宿舍系统没有拦截。或者一个宿舍显示还有空床但实际分配时报错说满了。原因这是典型的逻辑漏洞也是最容易在答辩时被老师当场问翻车的点。第一种情况是没做性别匹配校验分配方法里只查了宿舍是否满员第二种情况是 current_count 和实际数据不一致之前测试时手动往数据库插过数据没有同步更新 current_count 字段。解决业务校验必须四件套齐全——查学生是否已分配、查性别是否匹配、查是否满员、查宿舍状态是否正常。至于 current_count 不同步的问题把分配、退宿都收敛到 service 层的统一方法里禁止在 dao 层单独执行 UPDATE 跳过业务逻辑这样就不会绕开计数器更新。我见过有人图方便直接在数据库管理工具里手改数据导致 current_count 和实际入住人数对不上最后查了一下午才定位到问题。5.5 答辩文档 docx 打不开或排版错乱Word 文件在交付前一定要自查现象系统代码没问题运行也流畅但答辩前交付的“宿舍管理系统设计与实现.docx”文档在别人电脑上打开出现排版错乱、部分图片丢失或者干脆提示文件损坏。原因这里分几种情况。如果是自己用 WPS 或 Word 编辑的文档保存时版本兼容性没选对别人用 Office 2007 打开就可能乱。如果是在 Java 代码里用 Apache POI 自动生成的 docx 文件可能是生成过程中内存不足导致文件不完整。还有一种是文件名后缀是 .docx 但实际内容不是 Word 兼容格式只是改了后缀名。解决交文档前做三个动作。第一用 Microsoft Office 实际打开一次不要只用 WPS 检查第二如果论文里嵌有截图确认图片路径是相对路径或者图片已经插入文档而不是用了“链接到文件”的方式否则换个电脑就会丢图第三如果文档是从 Java 里用 POI 生成检查代码里是否有未关闭的输出流用 try-with-resources 确保 FileOutputStream 被正常关闭否则文件可能只写入了一半。文档的质量直接影响答辩评分代码做得再好文档一团糟也会让人觉得你没用心。6. 验收自查与答辩加分三个验证动作和一个可扩展方向6.1 功能闭环自查从分配到退宿走一遍完整流程系统做完不等于验收通过。我建议在答辩前一天按真实业务路径完整走一遍流程测试管理员登录 - 录入三名学生 - 分配宿舍男生分到男生楼、女生分到女生楼- 查看宿舍剩余床位 - 提交一条报修 - 处理报修 - 学生退宿 - 确认宿舍床位回收。走完这一圈如果每一步的数据都能在数据库对应的表里找到正确记录系统就没有大问题。另外补一个边界测试尝试把一名未分配宿舍的女生分到满员的男生宿舍系统应该拦截并提示尝试用错误的密码登录系统应该给出明确提示而不是直接崩溃。这两个动作能在答辩现场展示给老师看比单纯说自己“测试过了”更有说服力。6.2 答辩常用 SQL 自查这三个查询必须能脱口而出答辩时老师大概率会现场出题让你查某栋楼的入住情况或者某位学生的住宿记录。提前把下面三个查询对应到自己的系统上老师问的时候能直接在白板上写出来-- 查询某栋楼的入住情况 SELECT dorm_id, room_no, capacity, current_count FROM dormitory WHERE building 1号楼; -- 查询某学生的当前宿舍 SELECT s.student_id, s.name, d.building, d.room_no FROM student s LEFT JOIN dormitory d ON s.dorm_id d.dorm_id WHERE s.student_id 2021001; -- 查询某宿舍的报修记录 SELECT r.repair_id, r.description, r.status, r.create_time FROM repair_order r WHERE r.dorm_id (SELECT dorm_id FROM dormitory WHERE building1号楼 AND room_no101);这三条 SQL 覆盖了简单等值查询、多表关联查询和子查询是宿舍管理系统里最核心的数据操作。能当场写出这些比背一百个理论概念都管用。6.3 加分扩展给系统加一个数据导出功能如果时间充裕我建议给系统加一个“导出宿舍名单”功能用 Apache POI 把学生列表导出成 Excel 文件。这个功能实现起来不难大约五十行代码就能搞定但展示效果很好它能证明你不仅懂得入库还懂得把数据整理成业务可用的文件输出这在真实工作中更有价值。导出的内容可以包括宿舍楼栋、房间号、学号、姓名、性别。注意 POI 导出 Excel 后释放内存的细节在数据量大的循环里单元格写入很耗内存每写 100 行调用一次 flush 是个好习惯。我的个人习惯是这类课程设计项目文档永远是最后三天赶出来的质量一定差。下次再做我会先花半天搭好文档骨架把封面、目录结构、系统设计章节先写好代码写完直接往里填截图和验证结果。这样到最后一天你是在润色文档而不是在从零赶工。这个教训适用于任何一个以“设计与实现”结尾的项目。希望帮到你。本文还有配套的精品资源点击获取