简介:这是一套面向高校计算机专业学生与Java Web初学者、课程设计或毕业设计开发者的学生宿舍管理系统完整项目包,基于Java语言实现,涵盖住宿信息管理、宿舍与床位分配、日常行为记录、权限控制等核心模块,帮助读者理解从数据库设计到后端业务逻辑的完整开发链路。压缩包共661个文件,约77.19MB,以400个js、46个css等前端资源为主,辅以35个java源码、40个class、8个xml与8个html,并包含2个sql脚本、5个mp4辅导视频、部署文档及多份说明文档,覆盖MVC架构、Servlet与JSP、DAO数据访问、异常处理与测试调试等知识点。目前已有1615人学习下载。读者可获得可直接运行的源码、MySQL5与MySQL8两套适配项目、数据库结构文档、部署指南与配套讲解视频,便于对照复现功能、排查环境配置问题并快速完成二次开发或答辩准备。
1. 从一次宿舍分配翻车说起:这套 Java 系统到底解决什么问题
每年开学季,宿舍分配都是最让人头疼的事。我见过某高校后勤老师用 Excel 手动排床位,一个年级几百号人,排到凌晨两点,结果漏了三个转专业的学生,第二天被堵在办公室门口。问题不在于老师不认真,而在于工具本身撑不住这种数据量和并发修改。这套基于 Java 的学生宿舍管理系统,要解决的就是这类场景:把住宿信息、床位资源、日常行为记录统一到一个平台里,让管理员从表格里解放出来,让学生能自己查床位、改信息。
它适合两类人:一类是正在做 Java Web 毕设或课程设计的学生,需要一套结构完整、能跑起来的参考项目;另一类是从业者,想拿一个真实业务场景练手 MVC 分层和数据库设计。项目本身覆盖了学生信息管理、宿舍资源分配、权限控制、异常处理这些核心模块,技术栈是 Java + Servlet/JSP + MySQL,配套源码、数据库脚本、部署文档和辅导视频,拿到手就能对照着搭环境、跑流程。
2. 需求拆解与技术选型:为什么是 Java + Servlet/JSP + MySQL
2.1 功能需求:三个角色、六类核心操作
先把需求理清楚,不然后面写代码全是返工。这套系统的角色分三种:管理员、宿管员、学生。管理员权限最大,能管所有楼栋、所有学生、所有床位;宿管员只管自己负责的楼栋,能审批入住、退宿、调宿申请;学生只能看自己的住宿信息、提交调宿申请、修改个人联系方式。
核心操作归纳下来是六类:学生信息的增删改查、宿舍楼栋与房间的维护、床位的分配与释放、入住退宿的流程审批、日常行为记录(晚归、卫生检查等)、权限校验与登录会话管理。这六类操作背后对应的是数据库里至少五张表:学生表、宿舍楼表、房间表、床位表、行为记录表。表之间的关系是一对多和多对一交织,比如一个房间有多个床位,一个床位同一时间只能被一个学生占用。
提示:需求阶段一定要把「床位状态」单独拎出来设计。很多同学把床位占用信息直接塞进学生表,结果调宿的时候要改两张表,事务一复杂就出脏数据。
2.2 技术选型:Servlet/JSP 不是过时,是够用且好懂
有人会问,2025 年了为什么还用 Servlet/JSP,不上 Spring Boot?这个问题我在带课设的时候被问过无数次。答案很简单:这套系统的业务复杂度不高,Servlet/JSP 足够撑住,而且对初学者来说,没有 Spring 的自动配置黑匣子,请求从浏览器到 Controller 再到 DAO 的链路是透明的,调试的时候能看清每一步。
具体选型是这样的:后端用 Java Servlet 处理 HTTP 请求,JSP 负责页面渲染,DAO 层封装所有数据库操作,MySQL 做持久化存储。前端没有上 Vue 或 React,用的是 JSP + JSTL 标签库,配合少量 JavaScript 做表单校验。这样做的好处是部署简单,一个 Tomcat 就能跑,不需要前后端分离的联调成本。
数据库版本上,项目提供了 MySQL 5 和 MySQL 8 两个适配版本,这个细节很关键。MySQL 8 默认的认证插件和驱动类名跟 5 不一样,很多同学拿到的代码在 5 上跑得好好的,换到 8 就报Public Key Retrieval is not allowed,其实就是连接串少了个参数。
2.3 分层架构:MVC 落地到包结构
MVC 说起来简单,落地的时候包怎么分、类怎么放,才是真正影响后期维护的地方。这套项目的包结构大致是这样的:
// 典型的包结构示意 com.dorm ├── controller // 接收请求,调用 Service │ ├── LoginController.java │ ├── CaptchaController.java │ └── ExcelIOController.java ├── service // 业务逻辑,事务边界 │ ├── StudentService.java │ └── DormService.java ├── dao // 数据库访问,只做 CRUD │ ├── StudentDao.java │ └── BedDao.java ├── model // 实体类,对应数据库表 │ ├── Student.java │ └── Bed.java ├── config // 配置类 │ └── LoginConfig.java └── util // 工具类 └── CaptchaServiceImpl.javaController 层只做三件事:解析请求参数、调用 Service、返回视图或 JSON。Service 层负责业务规则,比如「一个床位不能同时分配给两个学生」这种校验就放在这里,同时它也是事务的边界。DAO 层只跟数据库打交道,不掺业务逻辑。这样分的好处是,改数据库不影响业务代码,改业务不影响页面渲染。
3. 数据库设计与核心模块实现:从表结构到登录拦截
3.1 表结构设计:五张核心表与索引策略
数据库设计是整个系统的地基。这套项目的表结构围绕「人-楼-房-床-行为」五个实体展开,核心表如下:
| 表名 | 关键字段 | 说明 |
|---|---|---|
| student | id, name, student_no, phone, bed_id | 学生信息,bed_id 外键指向床位 |
| building | id, name, manager_id | 宿舍楼,manager_id 指向宿管员 |
| room | id, building_id, room_no, capacity | 房间,building_id 外键指向楼栋 |
| bed | id, room_id, bed_no, status | 床位,status 标记空闲/占用/维修 |
| behavior_record | id, student_id, type, record_time | 行为记录,type 区分晚归/卫生等 |
索引方面,student_no 和 bed_id 上必须建索引,因为登录和调宿查询都走这两个字段。behavior_record 表的 record_time 也建议加索引,方便按时间段筛选。外键约束要不要加,看具体场景:加了能保证数据一致性,但批量导入的时候会拖慢速度。我一般会在开发阶段加上,上线前根据数据量决定是否保留。
3.2 登录与权限控制:一个拦截器搞定会话校验
登录模块看着简单,但权限控制做不好,学生能改别人信息,整个系统就废了。这套项目的做法是用一个 Filter 做统一拦截,配合 Session 存储登录态。核心代码如下:
// LoginConfig.java 中的拦截逻辑示意 public class LoginConfig implements Filter { // 不需要登录就能访问的路径 private static final String[] WHITE_LIST = {"/login", "/captcha", "/css/", "/js/"}; @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; String uri = request.getRequestURI(); // 白名单直接放行 for (String path : WHITE_LIST) { if (uri.contains(path)) { chain.doFilter(req, resp); return; } } // 检查 Session 中是否有登录用户 Object user = request.getSession().getAttribute("loginUser"); if (user == null) { response.sendRedirect(request.getContextPath() + "/login"); return; } // 角色权限校验:学生不能访问管理端接口 String role = (String) request.getSession().getAttribute("role"); if (uri.contains("/admin/") && !"ADMIN".equals(role)) { response.sendError(403, "无权限访问"); return; } chain.doFilter(req, resp); } }这段代码的关键点有三个:白名单机制避免登录页被拦截造成死循环;Session 校验保证未登录用户跳转登录页;角色判断防止学生越权访问管理接口。参数上,WHITE_LIST数组可以根据实际静态资源路径调整,role的值在登录成功时写入 Session,通常从数据库的用户角色字段读取。
注意:Session 超时时间要在
web.xml里显式配置,默认 30 分钟对宿舍系统来说偏长,建议改成 15 分钟,减少会话劫持风险。
3.3 床位分配与调宿:事务边界与并发处理
床位分配是这套系统里业务逻辑最重的模块。核心规则是:一个床位同一时间只能被一个学生占用,调宿时旧床位释放和新床位占用必须在同一个事务里完成,否则中途失败会出现「一个学生占两个床位」或者「床位凭空消失」的脏数据。
实现上,Service 层的方法用Connection的手动提交来控制事务:
// DormService.java 中调宿的核心逻辑 public boolean changeBed(int studentId, int newBedId) { Connection conn = null; try { conn = DBUtil.getConnection(); conn.setAutoCommit(false); // 开启事务 // 1. 检查新床位是否空闲 Bed newBed = bedDao.findById(conn, newBedId); if (newBed == null || !"FREE".equals(newBed.getStatus())) { throw new BusinessException("目标床位不可用"); } // 2. 释放旧床位 Bed oldBed = bedDao.findByStudentId(conn, studentId); if (oldBed != null) { bedDao.updateStatus(conn, oldBed.getId(), "FREE"); } // 3. 占用新床位 bedDao.updateStatus(conn, newBedId, "OCCUPIED"); studentDao.updateBedId(conn, studentId, newBedId); conn.commit(); // 全部成功才提交 return true; } catch (Exception e) { if (conn != null) { try { conn.rollback(); } catch (SQLException ex) { /* 记录日志 */ } } return false; } finally { DBUtil.close(conn); } }这里的事务边界划在 Service 方法上,DAO 层只负责单条 SQL 执行,不碰事务。setAutoCommit(false)之后,任何一步抛异常都会触发 rollback,保证数据一致性。并发场景下,如果两个宿管员同时给同一个床位分配学生,需要在updateStatus的 SQL 里加WHERE status = 'FREE'条件,通过数据库行锁来兜底。
3.4 验证码与 Excel 导入导出:两个容易被低估的模块
验证码模块看着小,但它是防暴力登录的第一道防线。项目里的CaptchaServiceImpl用 Java 的BufferedImage生成随机字符图片,存到 Session 里,登录时比对。关键参数是图片宽高和干扰线数量,宽高一般设 120x40,干扰线 5 到 8 条,太多会影响用户识别。
Excel 导入导出模块(ExcelIOController)是宿管员批量录入学生信息用的。实现上通常用 Apache POI 库,读取 Excel 时要注意单元格类型判断,数字和字符串要分开处理,否则学号会被读成科学计数法。导出的时候,表头和数据行要分开写,样式可以统一设置,但不要每行都创建新样式对象,否则数据量大的时候内存会爆。
4. 部署与联调避坑:从 MySQL 版本到 Tomcat 配置
4.1 环境准备:JDK、Tomcat、MySQL 的版本匹配
部署文档里写的是标准流程,但实际踩坑往往出在版本匹配上。JDK 建议用 8 或 11,Tomcat 用 8.5 或 9.0,MySQL 用 5.7 或 8.0。这三个东西的版本如果乱配,比如 JDK 17 配 Tomcat 8,启动的时候会报Unsupported class file major version,其实就是字节码版本不兼容。
MySQL 5 和 MySQL 8 的驱动类名不一样:5 用的是com.mysql.jdbc.Driver,8 用的是com.mysql.cj.jdbc.Driver。连接串上,8 需要加serverTimezone=Asia/Shanghai和useSSL=false,否则会报时区错误或 SSL 警告。项目里提供了两个版本的适配包,拿到之后先确认自己装的是哪个版本,再选对应的包导入。
4.2 常见问题排查:五个最容易翻车的点
现象一:启动 Tomcat 报 404,页面打不开。原因通常是web.xml里 Servlet 映射路径写错,或者项目没有正确部署到webapps目录。解决方法是检查 Tomcat 的server.xml中Context配置,确认docBase指向的是项目编译后的web目录,而不是源码目录。
现象二:登录后跳转空白页,控制台无报错。这种情况多半是 JSP 页面里的 EL 表达式没解析,原因是web.xml的版本声明太低,或者 JSTL 标签库没引入。检查web.xml的version属性,建议用 3.1 以上,同时在 JSP 头部加上<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>。
现象三:数据库连接池报Too many connections。原因是 DAO 层每次操作都新建连接,用完没关闭。解决方法是统一用DBUtil工具类管理连接,在finally块里调用close()。如果并发量确实大,可以引入 Druid 或 HikariCP 连接池,但课设级别用工具类就够了。
现象四:中文乱码,学生姓名显示成问号。三个地方要同时改:数据库建库时字符集用utf8mb4,连接串加characterEncoding=utf8,Tomcat 的server.xml里Connector标签加URIEncoding="UTF-8"。少改一个都会乱码。
现象五:调宿后床位状态没更新,刷新页面才正常。这是典型的缓存问题,JSP 页面被浏览器缓存了。解决方法是在 Controller 返回视图时设置响应头Cache-Control: no-cache,或者在 JSP 里加时间戳参数。
4.3 联调顺序:先通链路,再抠细节
联调的时候不要一上来就测所有功能,先跑通一条最短链路:登录 → 查学生列表 → 修改一个学生信息 → 退出。这条链路通了,说明数据库连接、Session 管理、DAO 层、JSP 渲染都没问题。然后再逐个模块测,每测一个模块,先测正常流程,再测边界条件,比如床位已满时分配、学号重复时导入。
提示:联调阶段建议把日志级别调到 DEBUG,SQL 语句和参数都打出来。很多问题看日志比看代码快。
5. 验收与答辩:怎么证明这套系统真的能跑
5.1 验收标准:功能、性能、代码三个维度
验收不是演示一遍就完事,得有可量化的标准。功能维度上,六类核心操作每类至少测三个用例:正常流程、边界条件、异常输入。比如床位分配,要测「有空床位时分配成功」「床位已满时提示失败」「分配不存在的床位时报错」。
性能维度上,课设级别不要求高并发,但至少要保证:单次查询响应时间在 500ms 以内,批量导入 100 条学生信息在 10 秒内完成,页面首屏加载不超过 2 秒。测试方法很简单,用浏览器开发者工具的 Network 面板看时间,或者写个简单的main方法循环调用 Service 层方法计时。
代码维度上,检查三个点:DAO 层有没有 SQL 拼接(防注入),Service 层有没有事务控制,Controller 层有没有权限校验。这三点做到了,代码质量就及格了。
5.2 答辩技巧:用「问题-方案-验证」三段式讲
答辩的时候不要照着 PPT 念功能列表,评委听了一天早就烦了。用「问题-方案-验证」的结构讲,每个模块两分钟:先说这个模块解决什么问题(比如「床位分配容易出脏数据」),再说你用什么方案解决(「Service 层手动事务 + 数据库行锁」),最后说怎么验证的(「模拟并发调宿,数据一致性通过」)。
评委提问环节,高频问题就三个:为什么选这个技术栈、数据库为什么这样设计、遇到的最大困难是什么。前两个按本文第 2 章和第 3 章的内容回答就行。第三个问题,建议讲一个真实的调试经历,比如 MySQL 8 驱动问题排查,比讲「学习了 Java 面向对象」有说服力得多。
5.3 从验收反推开发:我一般会留的三样东西
带过几轮课设之后,我养成了一个习惯:开发阶段就为验收做准备,具体是留三样东西。第一样是测试用例表,每完成一个模块就补一行,记录输入、预期输出、实际输出,答辩前直接拿这个表过一遍。第二样是部署脚本,把建库、导数据、改配置的命令写成一个bash脚本,换台机器也能五分钟跑起来。第三样是问题记录,调试过程中遇到的每个报错和解决方法都记下来,答辩被问到的时候直接翻记录,比临时编靠谱。
# 部署脚本示意:一键初始化数据库 mysql -u root -p -e "CREATE DATABASE dorm_db DEFAULT CHARSET utf8mb4;" mysql -u root -p dorm_db < sql/schema.sql mysql -u root -p dorm_db < sql/init_data.sql echo "数据库初始化完成,接下来配置 Tomcat 数据源"这个脚本看着简单,但验收的时候能省很多事。评委说「你现场跑一遍」,你总不能手动敲十几条 SQL 吧。
从那以后我每次做项目,都会在开发第一天就把验收清单列出来,写代码的时候对着清单走,而不是最后补。希望这套方案和这些踩坑经验,能帮你把毕设或课设顺利交出去。
本文还有配套的精品资源,点击获取