SpringBoot+Vue前后端分离毕设:房屋租赁系统源码与联调全解析 每年毕设季SpringBootVue前后端分离的项目几乎成了Java Web方向的“标配”。我前前后后带过的学生里有一大半做的都是管理系统类题目而房屋租赁管理系统又是其中最典型的业务场景之一——角色清晰、模块明确、数据库表不多但覆盖了增删改查的方方面面。这套项目如果只是拿到源码跑起来那确实不难但要真正吃透它、能应付答辩老师的连续追问背后值得拆的东西其实不少。这篇我会把一套完整的SpringBootVue房屋租赁管理系统平台的源码架构、SQL脚本设计、接口文档规范以及从环境搭建到前后端联调的完整复现过程一步步讲清楚。无论你是正在准备Java Web毕设的学生还是想完整跑通一个前后端分离项目练手的新人看完都可以直接照着操作并且能明白每一步为什么要这样做而不只是当一个“代码搬运工”。1. 项目整体设计与思路拆解1.1 为什么选SpringBootVue这套组合先说结论这套组合是目前Java Web毕设项目里性价比最高的选择没有之一。SpringBoot的核心价值在于“自动配置”和“开箱即用”。以前做SSH、SSM框架的项目光配置文件就要写一整天Spring、SpringMVC、MyBatis三个框架各来一套XML牵一发动全身。SpringBoot把所有繁琐配置封装成了约定内置Tomcat打成一个jar包直接就能跑对毕业生来说省掉的不只是时间还有大量“配置文件写错导致项目起不来”的崩溃瞬间。Vue这边也一样组件化开发让页面写起来非常舒服Element UI这类组件库拖拖拽拽就能把后台管理界面搭得像模像样。对比以前用JSPJQuery时代光是样式统一和前端校验就要折腾很久VueElement UI直接把这个门槛削平了。更关键的是前后端分离本身就是当前企业开发的主流形态你拿这套项目去面试聊“前后端分离、RESTful接口、交互鉴权”都有真实落地的案例可以说而不是停留在概念层。房屋租赁管理系统这个业务主题本身也选得妙。它的复杂度刚刚好比“学生管理系统”这类纯单表CRUD有更多的业务逻辑多角色、多状态流转、租赁订单和账单之间有联动但又不至于像电商系统那样涉及复杂的库存并发、支付回调。对于毕设来说既能体现工作量又能保证在两个月内做得完答辩时也有东西可讲。1.2 房屋租赁管理系统的业务模块划分拿到一套项目源码第一件事不是急着跑而是先把它的业务边界画出来。这套房屋租赁管理系统我拆开来看核心是三类角色加六个功能域。三类角色分别是管理员、房东、租客。管理员负责全局管理包括用户管理、房源审核、统计分析房东可以发布房源、下架房源、查看自己房源的租赁情况、生成账单租客可以浏览房源、发起看房、签订租赁合同、缴纳账单费用。注意同一个账号体系下通过role字段区分身份这是管理系统类项目最常见的做法而不是单独建三张用户表否则表结构会很臃肿。六个功能域基本覆盖了房屋租赁的全生命周期人员管理管理员对房东、租客的账号进行启停与审核房源管理房屋信息的增删改查价格、面积、户型、地址、状态租赁订单租客对房源发起租赁申请房东确认形成订单合同管理订单确认后生成租赁合同记录起止时间账单管理按月生成租金账单租客缴纳后更新状态看房记录租客预约看房房东记录查看时间与反馈这六个域之间的流转关系是房源发布 → 租客浏览 → 预约看房 → 发起租赁 → 订单签订 → 合同生成 → 账单缴纳。数据表之间的外键逻辑也是沿着这条业务主线走的。答辩时你能把这条主线讲清楚老师基本就不会认为你是纯抄代码了。1.3 技术栈选型与工具链搭配确认业务之后再看这套项目的技术栈装配。后端SpringBoot为核心持久层用的是MyBatis-Plus数据库MySQL鉴权用JWT构建工具Maven。前端Vue 2.x配Element UI请求库Axios路由Vue Router状态管理Vuex。这个组合在2024年的毕设市场里依然非常主流教程多、资料全、踩坑答案满网都是。有一个点我想多说一句为什么很多人建议Vue用2.x而不是3.x不是说Vue 3不好而是Element UI对Vue 3的适配版本是Element Plus两者在API用法上有不小差异大部分教学视频、网盘资料、学长留下的模板仍然基于Vue 2 Element UI。如果你是毕设求稳Vue 2生态的资料量是碾压级的如果你对Vue 3很熟那另当别论否则别在框架版本上给自己挖坑。工具链方面后端用IDEA数据库可视化推荐Navicat接口调试用Postman。这套工具组合在整个Java Web开发圈里认知度最高遇到问题随便就能搜到解决方案。环境版本的建议后面专门讲这里先不展开。2. 数据库设计与SQL脚本深度解读2.1 核心表结构设计思路拿到SQL脚本不要直接双击导入就完事建议先花半小时把表结构读一遍。这套系统我拆开看核心表可以分成“主表流转表记录表”三个层次。主表就是用户表和房屋表。用户表t_user是所有角色的载体字段包括id、username、password、real_name、phone、role、create_time。密码字段不要存明文脚本里初始化的密码通常都是BCrypt加密后的哈希值这一点答辩时很加分。房屋表t_house记录房东发布的房源信息核心字段有landlord_id、title、address、area、price、house_type、status。注意status字段的取值约定一般0表示未出租、1表示已出租数据库层面用tinyint存枚举不要用varchar存中文状态理由是节省空间、查询效率高、代码里也好做映射。借用一段简化版建表语句你感受一下设计风格CREATE TABLE t_user ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 用户ID, username varchar(50) NOT NULL COMMENT 登录用户名, password varchar(100) NOT NULL COMMENT BCrypt加密后密码, real_name varchar(50) DEFAULT NULL COMMENT 真实姓名, phone varchar(20) DEFAULT NULL COMMENT 手机号, role tinyint(4) DEFAULT 2 COMMENT 角色0管理员 1房东 2租客, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表;流转表包括租赁订单表t_rental_order、合同表t_contract、账单表t_bill。订单表记录租客的租赁申请字段包含house_id、renter_id、deposit、monthly_rent、months、total_amount、status金额全部用decimal(10,2)避免float的精度问题。合同表绑定订单和双方用户记录start_date、end_date。账单表与合同关联标记费用类型是租金还是水电费以及缴纳状态。记录表就是看房记录表t_look_record结构最简单但千万别省因为它是“租客从浏览到决策”这个中间环节的证据没有了它业务流程链是断的。2.2 SQL脚本里的业务约束与初始化数据看SQL脚本不要只看建表语句要重点关注索引、外键和初始化数据。这套脚本里用户表的username建了唯一索引是为了确保登录账号不重复房屋表对landlord_id建了普通索引是为了支撑“查询某房东名下所有房源”的高频操作。如果将来房源量大了address字段也可以建索引但毕设阶段没必要过度设计。初始化数据这块很多人忽略但它极其重要。一套完整的脚本除了建表至少会插入一个管理员账号、一个房东账号、一个租客账号外加几套房源和订单样例。这些数据不是多余的而是给你演示和自测用的。试想一下你启动项目之后发现登录页没有可用账号还得自己注册注册完要发房源、管理审核一套流程走完才能看到效果演示效率会非常低。有了初始化数据你启动后直接用预设账号登录前端页面立刻有内容可展示五分钟之内就能进入演示状态。另外一个小细节脚本末尾一般会有DROP TABLE IF EXISTS再CREATE TABLE的处理这是为了脚本可重复执行。如果你二次导入不需要手动去删除旧表直接执行新脚本就行这个习惯也值得保留在自己的项目里。2.3 导入SQL脚本的完整操作步骤导入这套SQL脚本说难不难但出错率最高的就是环境编码问题。我推荐两种方式任选其一。第一种Navicat图形化导入。打开Navicat连接到你的MySQL新建数据库命名建议和项目里application.yml配置的数据库名一致否则后面要改配置。比如项目里配的是room_rental你就建一个同名库。然后右键该数据库选择“运行SQL文件”选中项目的SQL脚本注意编码选UTF-8点击开始执行完成后刷新表列表能看到所有t_user、t_house之类的表就说明导入成功了。第二种命令行导入。在项目根目录执行这条命令mysql -u root -p room_rental init.sql前提是数据库room_rental已经创建好这条命令会直接把SQL文件里的内容导入该库。命令行导入有一个好处就是报错信息更直接你可以看到具体是哪一行出错。常见错误就是“Unknown database”说明你没建库或库名写错还有一种是中文乱码大概率是文件编码不是UTF-8用记事本另存为“UTF-8编码”重新导一次就好。导入完成后先别急着启动后端用Navicat打开任意一张表确认中文数据没有乱码再进入下一步。这个小检查能帮你把数据库层的问题和代码层的问题隔离开。3. SpringBoot后端核心实现解析3.1 项目分层结构与统一返回格式后端项目的代码结构打开src/main/java之后你会发现一个非常标准的四层结构controller、service、mapper、entity。entity对应数据库表controller层负责接收前端请求service层放业务逻辑mapper层用MyBatis-Plus封装的BaseMapper实现单表CRUD复杂查询就自己写注解SQL。这套分层设计在答辩时几乎是必问的。老师通常问为什么controller层不能直接写数据库操作这个问题的标准回答是分层让职责清晰controller只做参数接收和结果返回service层专注于业务规则比如下单时要同时校验房屋状态、计算总金额这些规则放在service里才能复用如果写在controller里那换个接口就复制粘贴一遍代码很快就烂了。还有一个值得关注的点是统一返回结构。所有后端接口返回的JSON格式是固定的一般是{ code: 200, message: success, data: { token: xxxxx, userInfo: {} } }前端Axios封装时就是基于这个结构做全局拦截的。code不为200时直接弹出错误提示不用在每一个页面里重复写错误处理。这个设计看起来简单但能让整个前端代码量少很多而且接口风格高度统一写接口文档时也更好描述。3.2 主要接口清单与文档关键规范这套系统背后的接口文档一般会把接口分成“认证模块”“房源模块”“订单模块”“账单模块”“系统管理模块”等几类。我挑几个核心接口看接口路径请求方式功能说明权限要求/api/user/loginPOST用户登录返回JWT token无需登录/api/user/registerPOST用户注册无需登录/api/house/listGET分页查询房源列表登录即可/api/house/addPOST发布房源管理员/房东/api/house/updatePUT修改房源信息管理员/房东/api/house/delete/{id}DELETE删除房源管理员/api/rentalOrder/createPOST创建租赁订单租客/api/bill/payPOST缴纳账单租客/api/user/listGET用户管理列表管理员这个接口清单的逻辑和业务模块完全对应。答辩前把这组路径背熟老师问“某个功能对应哪个接口”你能脱口而出印象分会好很多。接口路径的命名规范也值得学习用的都是RESTful风格资源名称用复数名词操作靠HTTP方法区分比如/api/house代表房源资源GET查询、POST新增、PUT修改、DELETE删除。路径中不出现动词像/api/getHouse这种写法是不规范的。另外接口返回状态码约定很清晰200成功、400参数错误、401未登录、403无权限、500系统异常这套语义和HTTP标准一致前端Axios拦截器也能精准处理。3.3 登录鉴权与数据安全细节登录鉴权这块是这套项目的技术亮点也是答辩时的重点提问区域。它采用的是JWT方案流程是这样的用户提交用户名密码到/api/user/login后端校验账号密码BCrypt加密比对通过后用密钥签发生成一个JWT token返回给前端前端拿到token存在localStorage里之后每次请求在请求头带上Authorization: Bearer token后端有一个拦截器统一校验所有/api/**请求除了login、register之外没有token直接返回401。这里有两个安全细节懂的人会自动加分第一密码加密用BCrypt不用MD5。MD5是摘要算法生日字典破解太容易了BCrypt每一步加盐同样的密码每次加密结果都不同安全性上了一个大台阶。第二MyBatis执行SQL一定要用#{}占位符做预编译不要用${}字符串拼接。${}存在SQL注入风险比如查询用户名时传入 or 11拼接出来的SQL会把整张表查出来用#{}则完全避免了这个风险这也是应付安全类追问最直接的防护措施。另外跨域问题在后端也需要有对策。虽然前后端联调时前端开了代理但如果你直接把前端和后端部署在不同端口没有代理转发的时候浏览器跨域报错会把你搞得焦头烂额。SpringBoot侧一般会写一个CorsConfig放行本地开发端口同时注意拦截器要放行OPTIONS预检请求否则前端POST请求还是会失败。这一条是很多新手的坑后面排查章节再细讲。4. Vue前端搭建与前后端联调4.1 前端项目结构与核心页面功能打开前端源码核心目录结构是src/api放接口请求封装src/router放路由配置src/store放Vuex全局状态src/views放页面组件src/utils放工具函数和Axios实例。这套组织方式很通用Vue项目基本都长这样。页面方面核心页面集中在几个地方。登录和注册页面在Login.vue和Register.vue租客端的首页房源列表在HouseList.vue房源详情和租赁申请在HouseDetail.vue房东端的我的房源在MyHouse.vue发布和编辑页在HouseEdit.vue管理员的用户管理在UserManage.vue房源审核在HouseAudit.vue。路由配置里最常见的设计是用meta.requiresAuth或meta.roles来控制页面访问权限在路由守卫里做判断没有登录就跳转到登录页角色不符就跳404。这里我建议学生都搞清楚一个逻辑前端路由守卫只是“看起来安全”真正决定权限的还是后端接口的鉴权前端隐藏某个按钮不等于接口就安全所以后端接口做角色权限校验比前端路由守卫重要得多。前端能演示的效果取决于后端数据。登录成功之后根据role字段动态调整左侧菜单租客看到的是“房源浏览”“我的订单”“账单缴纳”管理员看到“用户管理”“房源审核”“数据统计”房东看到“房源管理”“租赁订单”“账单生成”。把菜单和角色对应起来答辩时演示效果会非常直观。4.2 联调核心代理配置与Axios请求封装前后端分离项目联调时最大的困扰是跨域。本地开发时前端在8081端口后端在8080端口直接请求后端接口会被浏览器拦下来。解决方案不是在后端各种改跨域配置而是用Vue开发服务器的代理转发。打开vue.config.js你会看到这样一段配置module.exports { devServer: { port: 8081, proxy: { /api: { target: http://localhost:8080, changeOrigin: true, pathRewrite: { ^/api: /api } } } } };意思是前端请求/api/house/list时开发服务器自动把它转发到http://localhost:8080/api/house/list浏览器看到的请求是同源的就不会跨域了。这里注意changeOrigin: true必须开否则后端在某些情况下拿到的Host头不对会导致校验异常。Axios封装一般集中在src/utils/request.js核心逻辑在前面后端部分提到过请求拦截器加token响应拦截器统一解析code码。封装完之后你在页面里调用接口就只需写这么简洁的代码import request from /utils/request export function getHouseList(params) { return request({ url: /house/list, method: get, params }) }这个封装的收益是巨大的所有接口复用同一套逻辑。实测下来团队里如果有同学没做封装在几十个页面里各写各的错误处理最后联调阶段光是排错就能多花两天。早封装早省事。4.3 前端打包放进SpringBoot的部署方式毕设交付时演示环境不一定要部署到服务器很多时候本地跑起来就行。但有一种体验最好的部署方式值得掌握把Vue打包后的静态文件放进SpringBoot让前后端在同一个8080端口对外服务彻底消除跨域问题。操作流程分三步走第一步在Vue项目根目录执行打包命令npm run build打包完成后项目目录下会生成一个dist文件夹里面就是编译后的静态文件包括index.html、js、css等。第二步把dist目录下的所有文件复制到SpringBoot项目的src/main/resources/static/目录下。注意不要把dist整个文件夹放进去是把它里面的内容直接放到static根下。第三步重新打包后端项目mvn clean package生成的jar包用java -jar启动后浏览器直接访问http://localhost:8080你会看到Vue的前端页面。因为前端文件和后端接口同源所以不存在跨域问题一个端口搞定全部功能。这种部署方式在答辩时很讨巧老师如果想看效果你只要演示一个地址就行不用解释什么跨域、多端口体验很流畅。顺带提醒重新打包后端之前记得确认application.yml里的数据库配置还是正确的否则打包成功了也会因为连不上数据库而启动失败。5. 常见问题与排查技巧实录5.1 环境层面的坑版本匹配是第一道门槛这几年帮学生排查项目起不来的问题十有七八是环境版本不匹配而不是代码写错。先给你一张版本对照表照着配能少走很多弯路组件推荐版本说明JDK8或11SpringBoot 2.x配JDK8SpringBoot 3.x必须JDK17Maven3.6以上版本太低拉依赖会失败MySQL5.7或8.0两个版本在连接驱动上有差异Node.js14或16Vue 2项目在Node 16上最稳npm6.x或8.x跟着Node版本走这里要说一个高频翻车点就是SpringBoot版本太高。很多同学从网上用工具生成的SpringBoot项目一上来就是3.x代码倒是没什么问题但JDK还停留在8一启动就报“UnsupportedClassVersionError”。这个错误含义是编译用的JDK版本比运行时的JDK版本高。解决方法要么换SpringBoot 2.7.x版本要么升级JDK到17二者选其一别硬撑。MySQL方面8.0版本的驱动类名是com.mysql.cj.jdbc.Driver连接URL要带serverTimezoneAsia/Shanghai和useSSLfalse很多老项目资料里还是5.x时代的写法直接复制过来会启动报错。强烈建议以项目内application.yml为准不要从网上乱套模板。5.2 运行时的高频报错与解决思路项目启动之后各种运行时问题会接踵而来。我把这几年遇到的高频问题整理成一个速查表你可以收藏备用现象可能原因处理方式控制台报“Access denied for user”账号密码错误或权限不足核对application.yml数据库用户名密码用Navicat测试连接接口返回中文乱码连接串未指定UTF-8jdbc url加characterEncodingutf8前端请求一直Pending后端没启动或端口不对检查后端是否运行检查代理target端口提示401无token未登录或token过期重新登录检查localStorage中token是否存在页面打不开8080端口被占用其他程序占用端口换端口或查找占用进程并结束报错“Failed to configure a DataSource”数据库连接配置缺失检查application.yml是否配置了datasource前端npm install失败这个场景也很常见典型症状是下载到一半各种报错。先删掉node_modules文件夹和package-lock.json再重新执行npm install如果还失败用npm config set registry https://registry.npmmirror.com切换镜像源。这个操作是常规软件源管理实测下来能解决绝大多数依赖下载问题。还有一个非常隐蔽但很多人遇到的坑前端代理配好了但请求的URL没走/api前缀结果代理完全不生效。排查方法是打开浏览器F12看一下Network标签里的请求URL如果请求的是/house/list而不是/api/house/list代理配置就没覆盖到赶紧去请求代码里核对baseURL。5.3 答辩前必须做好的三件事项目跑通只是及格线答辩能讲清楚才是这道题真正的考核点。提前给你三个实操建议都是我从答辩现场总结出来的经验。第一准备一份五分钟的演示脚本。按顺序走一遍管理员登录 → 查看用户列表 → 查看房源列表 → 房源审核 → 房东登录 → 发布房源 → 租客登录 → 浏览房源 → 发起租赁 → 生成订单 → 缴纳账单 → 管理员查看全部订单。每一步的操作路径和背后的接口调用都要提前走几遍防止演示现场鼠标点错或接口报错措手不及。第二测试账号要提前确认。每个角色的账号都要测一遍密码是否和初始化数据一致角色权限是否正常。不要到了答辩教室才发现管理员账号进不去那会非常尴尬。用Navicat提前查一下t_user表就知道有哪些可用账号了。第三练好三个经典问题的回答为什么用JWT做登录鉴权、为什么用Redis缓存热门房源如果项目里用了Redis、订单状态流转的规则是什么。这三个问题覆盖了鉴权、性能优化和业务逻辑设计基本是老师最爱的提问方向。如果项目里没引入Redis就如实说没用然后补充一句“如果后续需要应对高并发场景我会考虑引入Redis缓存热门房源和分布式锁来防止订单重复提交”这种回答展示了思考纵深比硬编一个没用过的技术点更让人信服。写在最后的一些经验体会这套SpringBootVue房屋租赁管理系统我带学生反复跑了很多遍最大的感受是拿到一套完整源码真正把它变成自己的东西靠的不是一遍遍复制粘贴而是弄明白“每一张表为什么这样设计、每一个接口为什么这样规划、前端页面调用链路是怎么闭环的”。很多同学找我调试的时候报错截图一甩过来就问怎么解决但我都会反问一句这个报错是哪个环节的是数据库、后端、还是前端代理能够准确回答出这个问题的人其实已经离解决问题不远了。最后分享一个算是我个人习惯的小技巧跑通项目之后不要急着往下改代码先打开Navicat把t_house表的数据从“未出租”改成“已出租”然后去前端刷新页面看首页房源列表里那套房的状态是否跟着变了。如果变了说明后端接口、SQL查询、前端渲染这一整条链路是通的。这个动作比你在代码里翻半天文档更能让你快速建立起整套系统的全局认知。从这条链路出发再去给系统加新功能你会发现自己真的懂这套项目了而不只是会运行它。