☰
基于SpringBoot+Vue+MySQL的学生宿舍管理系统设计与实现
2026/10/9 12:58:32 网站建设 项目流程

每年到这个节点,总有同学在群里问宿舍管理系统怎么做。市面上的教程要么只有零散代码,要么数据库脚本和实体类对不上,要么压根跑不起来。我去年完整做了一套基于SpringBoot+Vue+MySQL的学生宿舍管理系统,从设计数据库到写接口、做页面、最后打包部署、写论文,一条龙走完,也拿了个不错的成绩。这篇就按“一个完整交付物”的标准,把源码结构、数据表设计、前后端核心实现、部署流程和论文写作要点全部拆开讲,希望能帮到正在做类似题目的同学。无论你是刚接触SpringBoot的全栈新手,还是需要参考一套完整毕业设计工程的同学,这篇文章里的思路和坑都值得你看完。

1. 项目整体设计思路与需求拆解

1.1 宿舍管理系统的业务边界

学生宿舍管理系统一听名字很普通,但它是典型的“业务边界清晰、角色分明、CRUD齐全”的项目,非常适合毕业设计。我建议先把角色和业务流程想清楚,再去谈技术。

我设计的系统分了三种角色:

  • 管理员:负责宿舍楼、房间、床位的维护,管理学生入住退宿,发布公告,处理水电费录入,分配维修单。
  • 宿管员:可以查看管辖楼栋的入住情况,处理学生发起的报修,登记来访或者日常检查结果。
  • 学生:查看公告、查看自己宿舍信息、提交报修、查询水电费、查看个人资料。

这样划分之后,每张表、每个接口的归属都非常清楚。比如报修单的流程是“学生提交 -> 宿管员查看 -> 管理员指派维修 -> 学生确认完成”,整条链路串起来,既有状态流转又能体现业务逻辑,比单纯的增删改查更有东西可写。

1.2 为什么选SpringBoot+Vue+MySQL这套组合

选型这事,我在论文里也花了不少篇幅解释。当时备选方案有几套,最简单的可以用JSP+Servlet,最“花哨”的可以上前后端分离加Redis加消息队列。但毕设不是生产环境,讲究的是“技术覆盖面和实现成本的平衡”。

SpringBoot的优点在于快速搭建、约定优于配置、内置Tomcat,写一个接口从新建到跑起来可能只要几分钟。Vue则让前端具备组件化开发能力,尤其是配合Element UI之类组件库,几行代码就能渲染出一个像样的管理后台表格页面。MySQL是应用范围最广的关系型数据库,网上教程、资料、报错解决方案几乎全覆盖,遇到问题不至于孤立无援。

这套组合下,导出的交付物非常明确:后端是SpringBoot工程源码,前端是Vue工程源码,数据层是SQL脚本,再加上论文和部署文档,正好对应题目里的“源码+数据库+论文+部署文档”。毕设答辩时,老师只要问“为什么用SpringBoot不用SSM”“前后端怎么交互的”“数据库为什么这么设计”,都能有清晰答案。

2. 数据库设计:从需求到表结构

数据库是整套系统的地基。我见过太多同学先写代码再补表,结果实体类跟字段对不齐,联调时各种报错。正确顺序应该是先梳理实体关系,再落地表结构,最后用代码生成或者工具同步。

2.1 核心表的设计细节

我的库名定为dormitory_db,核心表大概这些:

表名用途关键字段
sys_user用户账号表id, username, password, role, status
student学生信息表id, student_no, name, gender, phone, building_id, dorm_id, bed_no, status
building宿舍楼表id, building_name, floors, manager
dormitory宿舍房间表id, building_id, room_no, floor, bed_count, current_count, status
repair报修表id, student_id, title, content, create_time, status, handler
notice公告表id, title, content, publish_time, publisher
fee水电费表id, dorm_id, water_fee, electricity_fee, year_month, status
check_record查寝记录表id, student_id, date, status, inspector

学生表和宿舍的关系,我刻意在student表里冗余了building_id和dorm_id两个外键字段。为什么冗余?因为查学生列表时要频繁展示“住在几号楼几零几”,如果每次都join三张表,虽然也能查,但逻辑分散,而MyBatis-Plus查出来直接映射就行。为了应对极端情况,我又在student表建了联合唯一索引(building_id, dorm_id, bed_no),防止同一张床被安排两个人入住,这个索引后面可以写进论文的“数据库完整性设计”部分。

2.2 表设计里的几个关键取舍

首先是用户表到底要不要单独放。我的做法是sys_user只存账号密码和角色,学生表单独存详细信息,通过student_id关联sys_user。好处是登录模块只关心sys_user,不需要把学生表的字段全部加载进来,密码字段也不会在查询学生信息时被无意暴露。角色这块我没用spring security那套复杂的RBAC,直接用一个role字段区分,毕业设计足够,还能少写不少配置。

其次是逻辑删除字段。我在每张核心业务表都加了deleted字段,默认值为0,删除数据时改为1。这样做的好处是论文里可以写“采用逻辑删除,保留历史数据,便于追溯”,而且面试官问起来也能解释清楚。但坑也有,逻辑删除会让表的唯一索引失效,比如一个学生被“删除”后再重新录入,如果唯一索引还是(student_no),第二次插入就会冲突,所以我后来把唯一索引调整成了(student_no, deleted),确保删除后的记录不会阻挡新数据插入。

3. 后端开发:SpringBoot核心实现

3.1 工程结构与分层设计

我的后端工程结构是标准的四层结构,包路径大致如下:

com.example.dormitory ├── controller // 接口层 ├── service // 业务层,接口+实现 ├── mapper // MyBatis-Plus的Mapper接口 ├── entity // 实体类,对应数据库表 ├── dto // 接收前端参数的DTO ├── vo // 返回前端数据的VO ├── config // 配置类,跨域、拦截器、MyBatisPlus分页插件 ├── common // 公共类,统一返回结果、异常处理 ├── utils // 工具类,JWT工具等

分层的目的不是为了好看,而是为了让业务逻辑复用。比如宿管员查询学生列表和管理员查询学生列表,其实底层都是同一个service方法,只是在controller层做了权限校验,加了不同参数。如果全写在controller里,后面改个排序规则就要改两个地方,非常容易漏。

3.2 登录鉴权与JWT实现

登录这块我用的JWT方案,流程是:前端把用户名密码POST到/auth/login接口,后端校验通过后生成一个token返回,前端后续所有请求都在请求头里带上Authorization: Bearer token,后端通过拦截器解析token获取用户信息。

JWT工具类里有三个方法需要重点关注:生成token、解析token、判断token是否过期。token里我放了userId、username、role三个信息,过期时间设置成24小时。这样拦截器里只要把token解析出来,把用户信息塞进ThreadLocal,后续业务代码就能随时取当前登录人。

这里要提醒一个坑:SpringBoot版本不同,JWT依赖的引入方式也不同。如果你用的是SpringBoot 3.x,javax.servlet要换成jakarta.servlet,老教程里的代码直接复制过来会报找不到包。我当时用的SpringBoot 2.7.x,配合JDK8,依赖冲突最少,各种教程也都兼容。所以如果你对版本敏感度不高,建议直接上SpringBoot 2.7.18,别去追新,稳定最重要。

3.3 业务接口与统一返回格式

所有接口我都遵循RESTful风格,列表查询用GET,新增用POST,修改用PUT,删除用DELETE。返回格式统一封装成Result对象,结构是code、message、data三个字段,前端axios拦截器统一处理:

public class Result<T> { private Integer code; private String message; private T data; // 省略getter/setter }

这样前端拿到后端返回的数据后,不用对每个接口单独判断成功失败。我做了全局异常处理器@RestControllerAdvice,业务异常直接抛自定义BusinessException,全局处理器统一封装成Result返回,不会让异常堆栈直接暴露给前端。这个设计在论文里能单独写一节“统一异常处理机制”,答辩时很好讲。

分页查询用的是MyBatis-Plus的分页插件。特别注意,SpringBoot 3.x下需要加@Configuration配置分页拦截器,而且MyBatis-Plus版本要匹配。我用的MP版本是3.5.3.1,兼容性刚好。分页参数我固定用pageNum和pageSize,前端表格组件正好对应。

4. 前端开发:Vue页面与接口对接

4.1 环境搭建与项目初始化

前端我用的是Vue 2 + Vue CLI 4 + Element UI,这套组合虽然不如Vue 3新,但网上资料海量,而且Element UI的表格、表单、弹窗组件对管理后台来说特别顺手。如果你选Vue 3搭配Element Plus也可以,但要注意组件API有差异,比如插槽用法和事件名变化,别混着看教程。

环境搭建时最容易翻车的是node版本。Vue CLI 4对Node版本要求是10~14,你在Windows上如果装了Node 18以上,npm install会报各种ECONNRESET或者openssl错误。我当时折腾了很久,最后装了nvm来切Node版本,用12.22.12跑Vue CLI 4项目,一次通过。这个建议写在部署文档里,能帮别人少走很多弯路。

4.2 路由与权限控制

前端路由用了vue-router,在路由配置里给需要登录的页面配上meta: { requiresAuth: true }。全局前置守卫里,每次跳转先判断有没有token,没有就跳登录页,有就放行。然后根据用户角色动态决定显示哪些菜单,比如学生端只显示公告、报修、水电查询,不显示宿舍管理。

菜单这块我用的是侧边栏加路由表联动的方式,先定义一个菜单数组,菜单项的path和路由的path保持一致,然后v-for渲染。这样有个好处:同一套代码,管理员登录看到的菜单和学生看到的菜单不一样,视觉效果上就变成了“两个系统”,实际代码却完全兼容。答辩时老师问“多角色怎么处理”,这段就是现成的答案。

4.3 页面实现与接口联调

我先做的是登录页,登录成功存token和用户信息到localStorage,然后跳转到首页。首页是一个layout框架,左侧菜单、顶部导航、右侧内容区。模块页面基本套路都一样:进入页面调列表接口,表格渲染,点击新增弹表单,提交后重新加载列表。

axios封装这块也要说下。我在utils/request.js里创建axios实例,配置baseURL为后端的地址,比如http://localhost:8080/api,然后加请求拦截器往header里塞token,响应拦截器里判断result.code是否为200,不是就弹Message.error。这样业务代码里只需要关注数据本身,不用每个页面都写一遍状态判断。跨域问题我在后端的config里配置了CorsFilter,允许本地开发的前端端口访问,上线后交给Nginx做反向代理,就彻底不用管跨域了。

5. 项目部署:本地运行与服务器上线

5.1 本地环境部署流程

部署文档我写成了一份可以直接照做的步骤,分三部分:数据库导入、后端启动、前端启动。

数据库部分:在MySQL 5.7以上版本执行dormitory_db.sql脚本,注意字符集要设置成utf8mb4,否则中文全变问号。我见过很多同学直接双击运行sql文件,结果因为文件编码是UTF-8而客户端默认GBK,出现乱码甚至语法错误。正确做法是用Navicat或命令行source执行,执行前先执行SET NAMES utf8mb4;。

后端启动:修改application.yml里的数据库账号密码和端口,直接运行DormitoryApplication主类。SpringBoot内置Tomcat默认端口8080,如果被占用就改成8081。这里要注意,如果MySQL装在Windows上并开启了大小写敏感配置,表名和字段名对不上就会报Table not found,最好保持表名统一用小写。

前端启动:进入vue目录安装依赖,npm install再npm run serve,默认跑在8080端口。开发模式下通过Vue CLI的proxyTable代理把/api开头的请求转发到后端8080,这就能正常联调。

5.2 生产环境部署方案

生产环境我用的是一台Linux服务器加宝塔面板。后端打包成jar包,前端打包成dist目录,最终访问架构是Nginx监听80端口,静态文件直接由Nginx托管,/api开头的请求反向代理到SpringBoot的8080端口。Nginx里关键的配置就是location /api { proxy_pass http://127.0.0.1:8080; },注意proxy_pass后面的URL不要带路径,否则转发时前缀会被改写。

我把这套配置写成了一节面向完全没有服务器经验同学的“傻瓜式部署”,包括怎么开放安全组端口、怎么用JDK17跑jar包、怎么把前端dist目录上传到指定站点目录。部署文档的作用不是展示自己多会用Linux命令,而是让拿到这套资料的人能真的把项目跑起来。

5.3 打包过程中的教训

打包最大的坑是前端请求地址写死了。如果你在axios里写了http://localhost:8080/api,那么部署到服务器后,用户浏览器会在自己电脑上找localhost,接口全挂。正确做法是用相对路径/api,开发时靠proxy转发,线上靠Nginx转发,这样无论在哪个环境都不用改代码。

后端的坑是打包时resources目录下的配置文件如果用了外部配置覆盖,jar包启动会报找不到配置。我的做法是配置文件全部放在resources里,用maven打包,打包后先在本机java -jar启动一遍确认没问题,再传到服务器。上传之后用nohup java -jar dormitory.jar > log.txt 2>&1 & 启动,日志输出到文件,排错也有依据。

6. 常见问题与排查实录

6.1 后端常见报错

报错信息原因解决方案
Access denied for user 'root'@'localhost'MySQL账号密码不对或host限制检查application.yml配置,确认密码和MySQL授权host
Unknown column 'deleted' in 'where clause'实体类用了逻辑删除但表没该字段建表SQL补上deleted字段并设为默认0
Failed to determine a suitable driver class驱动或数据源配置不完整检查pom.xml是否包含mysql-connector-java,检查url格式
Cannot load driver class: com.mysql.cj.jdbc.Driver老版本驱动类名错误用mysql-connector-java 8.x版本,驱动类名用com.mysql.cj.jdbc.Driver
HikariPool-1 - Exception during pool initialization数据库服务没启动或密码错误先去命令行测试mysql -u root -p能否登录,再检查配置
时间字段总是比北京时间早/晚8小时时区配置问题JDBC url加serverTimezone=Asia/Shanghai

6.2 前端常见报错

前端最头疼的问题是npm install那一关。千万不要一上来就跑npm install,先确认三件事:Node版本是否匹配、是否设置了npm镜像源、项目目录下有没有package.json。如果报错信息里有gyp ERR,基本都是node-gyp编译原生模块失败,要么换Node版本,要么升级node-sass为dart-sass。

Vue项目还有一类经典问题:页面能打开但接口全403。排查思路是打开F12看网络请求,如果请求头里没有Authorization字段,就是axios拦截器没生效;如果有token但后端报401/403,那就是后端的JWT拦截器把登录接口也拦截了。正确做法是在拦截器排除配置里把/login和/error排除掉。

6.3 数据库相关常见问题

MySQL这块的坑比较隐蔽。比如中文乱码,要找三个位置:数据库字符集、表字符集、连接字符串里的characterEncoding=utf8mb4。三个地方必须一致,否则总有一个环节会出错。还有一次我把导入SQL脚本放到宝塔上执行,提示Unknown collation,后来发现是SQL文件里写了utf8mb4_0900_ai_ci,这是MySQL 8.0才有的排序规则,MySQL 5.7下根本不认识。解决办法是把排序规则改成utf8mb4_general_ci。

7. 论文写作与答辩准备

7.1 论文结构怎么搭

论文的章节安排直接影响答辩印象分。我的论文章节是:绪论、相关技术介绍、系统需求分析、系统设计、系统实现、系统测试、总结与展望。很多同学把重点放在技术介绍上,罗列一堆SpringBoot和Vue的官方文档内容,这其实很浪费篇幅。老师真正想看到的是“你做了什么决策、为什么这么决策”,而不是“Spring Boot是什么”。

在系统设计章节,我把ER图、用例图、功能模块图都画得非常细致,数据库设计里每一张表都配上字段说明表格。答辩现场老师翻开论文,看到表格比看到大段文字更愿意认真看,对你的好感度提升非常明显。

7.2 答辩准备的核心问题

答辩时极大概率被问到的问题,我提前整理了出来:登录流程怎么实现的?为什么密码要加密,加密方式是什么?前后端如何实现跨域访问?数据库为什么这么设计,是否有缓存?报修单的状态是怎么流转的?如果数据量大了怎么办?这些问题都需要能从自己的代码里举例子,而不是背概念。

比如“数据量大了怎么办”,我的回答是:当前系统用MySQL单机存储,通过分页查询限制单次返回条数;如果后续数据量增长,可以在student和repair表上按时间加索引,也可以引入Redis缓存热点数据,比如公告列表和宿舍空闲房量。这个回答既承认了工程的局限,又给出了可扩展的方向,比硬吹自己用了分布式架构要诚实且有逻辑。

在论文里,我还专门加了一节“系统测试”,写了测试环境、测试用例表、功能测试结果、性能测试摘要。性能测试我只用了JMeter简单压了一下登录接口,100并发下平均响应时间在80ms以内,这个数据虽然不复杂,但足以证明系统的基础稳定性。

最后补充几个忍不住想说的经验

第一,别太追求代码量。宿舍管理系统这种题目,核心功能做到完整、界面做到整洁、文档做到规范,基本就是优秀区间。那些动不动堆几万行代码的同学,反而容易在答辩时说不清楚自己写的是什么。

第二,版本选择上要克制。SpringBoot 2.7.18加Vue 2加MySQL 5.7是经过大量验证的稳定组合,新手能避开很多版本坑。如果你身边有人用SpringBoot 3.0踩了一周坑最后把JDK、各种依赖全换了一遍,那纯属自己给自己挖坑。

第三,部署文档一定要自己照着完整走一遍再交付。我认识很多人写完部署文档后从没试过从零部署,结果发给别人后第一步就卡住。你自己实际操作一遍,把每一步执行命令的真实输出、每个配置项的位置都截图确认,拿到手的人才能真正跑起来,这一点比写多少字都有用。用心把这些细节补齐,不管你是自己用还是要参考这套思路去重新做,都不会亏。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询