简介:面向毕业设计场景的民宿短租小程序完整项目,基于微信小程序+SSM+MySql架构开发,适合需要完成课程设计或快速入门前后端分离开发的计算机专业学生。系统围绕民宿信息展示、在线预订、后台管理三条主线展开,包含用户端小程序、房主端管理与管理员控制台,可用于替代传统中介场景下的民宿租赁流程。
资源包含996个文件,压缩包约38.58MB。文件类型以vue前端组件、java后端逻辑、xml与sql配置文件及mysql数据库脚本为主,另有mp4演示视频和doc毕业论文文档。vue与java代码支撑前后端交互流程,sql与properties便于快速还原数据库环境,mp4和doc则用来辅助演示与论文撰写。
已有335人浏览学习。整套资料相当于可直接运行的完整项目方案,覆盖管理员、房主、用户三种角色,从数据库建表到后端接口实现再到小程序页面均有迹可循,适合边对照代码边梳理毕业设计答辩思路,也能借此减少环境搭建和基础业务开发的时间投入。
1. 民宿短租小程序:微信小程序 + SSM + MySQL 的完整部署链路
做毕设选型的时候,很多人第一眼看到“民宿短租小程序”会觉得它就是个普通 CRUD 项目,但真正把源码拆开看,价值点恰恰在业务链路上:租客找房、房主管房、平台方监管,三类角色共用一套微信小程序 + SSM + MySQL 的后端,却各自有清晰的权限边界。这套系统把中介环节直接砍掉,民宿信息、价格、图片全部线上化,对准备答辩、想找一个能讲清楚前后端数据流转的 javaweb 完整案例的人来说,是非常合适的复现对象。它覆盖了微信小程序端、Vue 管理后台、SSM 接口层、MySQL 数据库四块内容,跑通它,相当于把 Web 开发的主线流程完整走了一遍。
2. SSM 三层的角色分工:表结构设计与权限边界
2.1 为什么选 SSM + MySQL 而不是 Spring Boot:答辩友好,三层可见
这套工程的后端是经典 SSM,也就是 Spring + SpringMVC + MyBatis。Spring 负责管理对象和事务、SpringMVC 负责把 URL 请求路由到 Controller、MyBatis 负责把 Service 层的调用翻译成 SQL,分工非常明确。现在新项目大多直接用 Spring Boot,但毕设场景下我会更推荐 SSM,原因很实际:Spring Boot 把大量配置藏进了 starter,答辩时老师问“autoconfigure 里到底做了什么”,你很难现场把链路讲清楚;SSM 的源码目录拉开就是 controller、service、mapper 三个包,每一层做了什么一眼能看明白,回答“请求进来之后数据是怎么流转的”这类问题会轻松很多。
从工程结构上看,后缀 .classpath 表明后端工程是 Eclipse 工程,直接用 IDEA 导入为 Eclipse 项目或普通 Java 项目都能打开。技术版本搭配上,常见组合是 JDK 1.8 + Tomcat 8.5/9 + MySQL 5.7 或 8.0,这套组合兼容性最好。这里有一个关键坑要提前说:如果你本机装的是 Tomcat 10 及以上,SSM 项目的 javax.servlet 包名会直接对不上,启动必报错。所以跑这套系统前,先把 Tomcat 版本降到 9 以下。
至于前端为什么选微信小程序而不是 H5,除了微信生态里免安装、分享方便之外,还有一层现实原因:毕设演示时,用微信开发者工具跑一个小程序项目,比在浏览器里开一个 H5 页面更有“完成度”。更重要的是,这套资源里把预订、订单、后台管理三端数据串成了一条完整链路,这在答辩时的演示效果比单个页面堆砌要强很多。
2.2 用户、房主、管理员的三类角色怎么落表:role 字段与数据表清单
民宿短租系统的核心是三类操作者:普通用户浏览房源并下单,房主维护自己的民宿和订单,管理员管理全平台的信息与订单。一般做法是把房主身份直接放进 user 表,用 role 字段区分,而不是单独建一张 landlord 表。这样设计的好处是登录逻辑统一,小程序端只需要一个 login 接口就能区分身份,后续房主端和管理员端的权限控制都通过拦截器判断 role 实现。
user 表字段大致如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 主键,自增 |
| username | varchar(50) | 登录名 |
| password | varchar(64) | 加密后的密码 |
| phone | varchar(20) | 手机号 |
| role | tinyint | 1 普通用户,2 房主,3 管理员 |
| create_time | datetime | 注册时间 |
民宿表是另一个关键表,它关联了房主和订单:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 主键 |
| landlord_id | int | 关联 user 表的房主 id |
| title | varchar(100) | 民宿标题 |
| address | varchar(255) | 详细地址 |
| price | decimal(10,2) | 每晚价格 |
| cover | varchar(255) | 封面图片路径 |
| description | text | 房源描述 |
| status | tinyint | 1 上架,0 下架 |
| create_time | datetime | 发布时间 |
订单表是整个系统的业务核心,它把用户和房源联系在一起:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 主键 |
| order_no | varchar(32) | 订单编号 |
| user_id | int | 下单用户 |
| house_id | int | 关联民宿 |
| check_in_date | date | 入住日期 |
| check_out_date | date | 离店日期 |
| amount | decimal(10,2) | 订单金额 |
| status | tinyint | 1 待付款,2 待入住,3 待评价,4 已完成,0 已取消 |
| create_time | datetime | 下单时间 |
订单状态机是这套系统的灵魂,从待付款到待入住再到待评价、已完成,每一步都是小程序端和 Vue 后台端共用同一个订单表来驱动的。房主在后台看到待入住的订单,就说明用户已经完成支付流程;管理员则能看到全部订单,处理异常取消或退款。这种状态流转非常值得在答辩时重点讲,它直接说明数据库设计不是简单堆表,而是为业务流程服务的。
3. 把工程跑起来的三件事:环境对齐、数据库导入与批处理脚本
3.1 环境清单:JDK、Tomcat、MySQL、微信开发者工具一个都不能少
在导入代码之前,先把环境对齐,否则后面每一步都会冒出奇怪的报错。我的建议版本清单如下:
| 软件 | 版本建议 | 主要作用 |
|---|---|---|
| JDK | 1.8(8u202 或更高) | 后端编译与运行 |
| Tomcat | 8.5 或 9.0 | SSM 后端容器 |
| MySQL | 5.7 或 8.0 | 数据存储 |
| Navicat | 15/16 均可 | 导入 SQL、调试数据 |
| 微信开发者工具 | 稳定版即可 | 运行小程序前端 |
| Node.js | 12 或 14 LTS | 编译 Vue 后台 |
这里最容易出问题的就是 Tomcat 版本,前面说了 Tomcat 10 的 javax 包名问题会导致 SSM 直接起不来,所以装 8.5 是最稳的。MySQL 版本 5.7 和 8.0 都能跑,但连接配置有区别,后面 jdbc 配置里会专门讲。Node.js 也别装最新的 20 以上版本,Vue 后台用的依赖大多比较老,node 版本太高会出现 node-sass 编译失败。
数据库方面,建议先装好 MySQL 服务并记住 root 密码。Windows 下安装 MySQL 8 时选择默认端口 3306,认证方式选“Use Legacy Password Encryption”这一项,可以避免后续老驱动连不上新密码算法的问题。
3.2 数据库导入与连接配置:用 Navicat 或 mysql 命令完成初始化
资源里带了 .sql 数据库文件,用 Navicat 导入是最快的:先新建数据库,名字按 sql 文件里的库名来,字符集选 utf8mb4,然后右键“运行 SQL 文件”选择 .sql 文件,执行完就会自动建出所有表。如果你习惯命令行,也可以用 mysql 命令:
mysql -u root -p < mini_homestay.sql执行后会提示输入 root 密码,然后开始逐条执行 SQL。这里要注意的是导入前先确认当前连接能访问本地 MySQL,否则会直接报连接错误。数据库导入完成后,需要去后端源码里找到 jdbc.properties 或 db.properties 配置文件,把数据库连接改成你自己的账号密码。文件位置一般在 src/main/resources 下,改法如下:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mini_homestay?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai jdbc.username=root jdbc.password=你的实际密码这段配置里三个参数最关键:useSSL=false 是为了关闭 MySQL 8 默认的 SSL 握手,不关会报 SSL 连接错误;serverTimezone=Asia/Shanghai 是给数据库连接指定时区,不写的话时间字段查询会报错;characterEncoding=utf8 保证小程序端传过来的中文不会变成乱码。改完保存,数据库连接就通了。
3.3 三个 bat 脚本的使命:install 装依赖,run 起后端,build 出后台
资源压缩包解压后能看到 1-install.bat、2-run.bat、3-build.bat 三个批处理文件,命名非常直白,就是安装、运行、构建三步。1-install.bat 一般负责初始化环境,比如建库导数据或者检查本地依赖;2-run.bat 负责启动后端 Tomcat 和小程序依赖;3-build.bat 是编译 Vue 管理后台,生成 dist 静态文件。
以 run 脚本为例,常见的启动逻辑如下:
set CATALINA_HOME=D:\apache-tomcat-8.5.87 call %CATALINA_HOME%\bin\startup.bat start http://localhost:8080/homestay第一行是设置 Tomcat 安装路径,CATALINA_HOME 必须指到你本机实际的 Tomcat 目录,否则脚本找不到启动程序;第二行调用 startup.bat 启动后端;第三行自动打开浏览器访问系统首页。如果你不想用脚本,也可以直接在 IDEA 里配置 Tomcat Server,把后端工程打成 war 包部署到 Tomcat 的 webapps 目录下,效果是一样的。
微信开发者工具部分不需要脚本,直接导入小程序端目录,修改 utils/request.js 里的 baseURL,把 localhost 改成本机 IP 或保持 localhost:8080 即可。Vue 后台如果要用 3-build.bat,先确认全局已安装 Node.js,然后双击执行,它会自动 npm install 并执行 npm run build。
4. 微信小程序端怎么连上后端的:请求封装、登录态与排序查询
4.1 页面与流程:从浏览房源到提交订单的五步路径
小程序端页面不算多,但每一页都对应真实业务动作。核心路径是:首页 → 房源列表 → 房源详情 → 下单页 → 订单中心。首页负责展示推荐民宿和搜索入口;列表页根据城市或关键词拉取房源;详情页展示图片、价格、描述,并选择入住和离店日期;下单页确认金额并提交订单;订单中心则展示当前用户的所有订单状态。
日期选择这里,小程序用的是 picker 组件,入住和离店各一个选择器,本质上对应后端订单表里的 check_in_date 和 check_out_date 两个字段。很多初学者会在这里用两个单独的输入框让用户手填日期,但微信小程序的日期键盘格式不统一,解析很容易出错。正确做法就是 picker mode="date",选完直接拿到标准化格式。
下单的数据流也很清晰:小程序端把 houseId、checkInDate、checkOutDate 通过 wx.request POST 到后端 /api/order 接口,Controller 解析参数后交给 Service 层,Service 校验房源状态为上架、日期没有冲突,然后插入 order 表并生成订单号,最后把订单号返回给小程序端展示。房主端在 Vue 后台的订单列表里看到这条新记录,状态是待入住。
4.2 把 wx.request 封装成 Promise:统一入口、统一错误处理
小程序自带 wx.request 是回调写法,页面多了以后每个页面都写 success/fail 会非常乱。这套项目里常见的做法是封装一个统一的 request 工具,把 baseURL、header、错误提示集中处理。我自己改项目时一般会写成这样:
const request = (url, method = 'GET', data = {}) => { const token = wx.getStorageSync('homestay_token'); return new Promise((resolve, reject) => { wx.request({ url: 'http://localhost:8080/homestay/api' + url, method: method, data: data, header: { 'Content-Type': 'application/json', 'Authorization': token ? token : '' }, success: (res) => { if (res.statusCode === 200) { resolve(res.data); } else { wx.showToast({ title: '请求失败', icon: 'none' }); reject(res); } }, fail: (err) => reject(err) }); }); }; module.exports = request;封装后所有页面都通过 request('/house/list', 'GET', params) 这种方式调用,返回的是 Promise,配合 async/await 写起来更像同步代码。header 里统一带 Authorization,后端拦截器就能从请求头里解析当前登录用户。baseURL 是 localhost:8080,真机调试时要改成电脑的局域网 IP,否则手机访问不到你的 Tomcat。
登录态一般用 wx.setStorageSync 缓存 token。注意 token 要设过期时间,常见做法是存一个对象,里面同时带 expire 时间戳,每次启动小程序时先检查是否过期,过期就重新登录。搜索关键词“微信小程序设置缓存时间”相关的做法就是这个思路。
4.3 民宿列表排序:把价格、评分参数传到 MyBatis 动态 SQL
房源列表页一般会有排序选项:按价格升序、按评分降序。这个功能看起来小,但很容易写翻车,因为 order by 后面不能直接拼接用户传过来的参数,否则有 SQL 注入风险。MyBatis 里正确的做法是用 choose 标签做白名单判断:
<select id="listHouses" resultType="com.example.entity.House" parameterType="map"> select * from house <where> <if test="keyword != null and keyword != ''"> and title like concat('%', #{keyword}, '%') </if> <if test="status != null"> and status = #{status} </if> </where> order by <choose> <when test="sort == 'price'">price asc</when> <when test="sort == 'rating'">rating desc</when> <otherwise>create_time desc</otherwise> </choose> </select>这个 XML 做了两件事:where 部分根据 keyword 做模糊查询,status 字段过滤上下架房源;order by 部分把 sort 参数映射到固定的字段和排序方向,不在白名单里的值就走默认的 create_time desc。这样既实现了搜索结果按价格和评分排序,又不会因为用户传了个乱值导致 SQL 拼接报错。小程序端只需要在 request 里带上 sort=price 或 sort=rating,后端就能正确响应。
如果排序逻辑不经过 MyBatis 而是直接在 Java 里用 list.sort 做,数据量小的时候看起来也能跑,但一旦民宿数量增加到上千条,全表查出来再排序的性能就很差了。把排序下推到 MySQL 执行,才是这个场景下正确的做法。
5. 部署与运行中的五个常见坑:从 MySQL 连接失败到小程序白屏
5.1 Navicat 导入 SQL 报错 1064:先建库,再导表
现象:用 Navicat 双击打开 .sql 文件并运行,执行到一半弹出错误,Error 1064 语法错误,或者表只建了一半。
原因:绝大多数情况是连接所选的目标库不对,SQL 文件里如果写了自己建库语句但当前连接没切换过去,就会把表建到错误的位置;另外字符集不一致也会触发这类报错。
解决:先手动创建一个数据库,字符集选 utf8mb4,然后退出 SQL 文件预览窗口,右键这个新建的数据库,选择“运行 SQL 文件”,选中 .sql 执行。如果还报错,把文件开头的 CREATE DATABASE 和 USE 语句注释掉,只保留建表和插入语句。
5.2 MySQL SSL 连接错误:useSSL 参数要显式关闭
现象:Tomcat 启动后日志里出现 SQLNonTransientConnectionException: SSL connection error,或者 Could not create connection to database server,后端接口全部 500。
原因:MySQL 8 默认开启了 SSL 连接,而项目里的 JDBC 驱动版本比较老,或者连接串里没有声明 useSSL=false,双方握手阶段就断掉了。
解决:改 jdbc.properties,在 url 后面加上 useSSL=false 和 serverTimezone=Asia/Shanghai。如果已经加了还报错,把 mysql-connector-java 驱动换成 8.0.33 或 5.1.49,这两个版本兼容性比较好。
5.3 error 2002 (HY000):本地 MySQL 服务没起来的典型症状
现象:命令行执行 mysql -u root -p 回车后,直接提示 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock',项目里所有查库操作都失败。
原因:这个报错通常不是密码错了,而是 MySQL 服务根本没有启动,客户端找不到套接字文件。Windows 下常见是服务没有设置成自动启动,Linux 下则是 mysqld 进程没拉起来。
解决:Windows 打开服务管理器,找到 MySQL80 或对应服务名,右键启动并设为自动;Linux 执行 systemctl start mysqld 或 service mysql start。启动后再执行 mysql -u root -p,能进入命令行就说明连接正常。
5.4 小程序请求报“不合法域名”:本地调试先跳过校验
现象:微信开发者工具里点击按钮发起请求,控制台报 url not in domain list,或者 request:fail,页面白屏,但同一个地址在浏览器里能正常打开。
原因:微信平台安全限制,wx.request 只能请求已配置到小程序后台白名单里的 HTTPS 域名。你用 localhost 或局域网 IP 调试时,这些地址不可能在白名单里,所以直接被拦截。
解决:开发调试阶段,在微信开发者工具右上角“详情 → 本地设置”里勾选“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”。上线前再去小程序管理后台配置 request 合法域名,把后端接口的备案域名加进去。
5.5 Vue 后台 build 一闪而过:先把 node_modules 装齐
现象:双击 3-build.bat,命令行窗口一闪就消失,后台管理系统的 dist 目录没有生成,或者生成了但打开是白屏。
原因:bat 脚本执行失败后窗口自动关闭,看不到真实报错。常见原因是项目根目录缺少 node_modules,或者 Node.js 版本太高导致依赖安装失败。
解决:在 Vue 后台目录下先执行 npm install,装完再执行 npm run build。如果 npm install 报错,把 Node.js 卸载换成 14 LTS,再删掉 node_modules 和 package-lock.json 重新安装。想要排查脚本问题时,在 bat 文件最后加上 pause,窗口就不会闪退了。
6. 两个实用技巧:用 .bak 文件做组件级回滚,以及调整连接池参数
6.1 管理后台改崩了?先找 .bak 文件
资源包里有不少 .bak 后缀文件,比如 IndexHeader.vue.bak、IndexAsideStatic.vue.bak、update-password.vue.bak,很多人第一次看到会以为是垃圾文件直接删掉,其实这些是作者调试后台管理系统时留下的备份文件,很有用。Vue 后台改着改着把布局组件改崩了,页面白屏,这时候不需要重新解压整个资源包,直接把对应的 .bak 文件覆盖回去就能恢复:
copy /Y IndexHeader.vue.bak IndexHeader.vue这个操作本质上是组件级别的后悔药。它比 Git 回滚更轻量,因为整个管理后台能跑的版本就被固定在这些 .bak 文件里。当我改坏了某个页面时,先看这个组件有没有同名 .bak,有就直接覆盖,没有才去翻 Git 历史。从那以后我每次改 Vue 组件前,都会先复制一份 .bak 留着,希望帮到你。
6.2 jdbc.properties 里连接池参数怎么调
数据库连接池参数在 jdbc.properties 或者 Spring 的 datasource 配置里,虽然默认值能跑,但并发上来就会暴露问题。常见参数调整如下:
druid.initialSize=5 druid.minIdle=3 druid.maxActive=20 druid.validationQuery=SELECT 1 druid.testWhileIdle=trueinitialSize 是启动时初始化的连接数,minIdle 是空闲时最少保留的连接数,maxActive 是最大活动连接数。毕设和本地开发场景下,maxActive 设 20 完全够用;如果部署到服务器上有人访问,可以提高到 50,但过大反而会拖垮 MySQL。validationQuery 设置为 SELECT 1 是因为 MySQL 连接被防火墙或空闲超时断开后,连接池需要有一条轻量 SQL 来探测连接是否还有效。testWhileIdle=true 则保证空闲连接被回收前先做一次探测,避免用户请求突然拿到一个已经失效的连接。调完参数重启 Tomcat 才会生效。
本文还有配套的精品资源,点击获取