1. 需求拆解与技术选型思路
1.1 课题到底在做什么:从功能清单看系统边界
每年一到毕业设计选题季,“基于Spring Boot的大学生租房系统”几乎都会出现在各个高校的选题列表里。这个题目能被反复选中,核心原因在于它踩中了几个关键点:业务场景贴近学生日常生活、功能复杂度适中、技术栈主流且就业市场认可度高。
先把这个系统的边界划清楚。大学生租房系统的核心用户是三类人:普通学生(租客)、房东(或个人二房东)、系统管理员。围绕这三类角色,系统要解决的核心问题也很明确:
- 学生找房难:需要按区域、价格、房型筛选房源,查看房屋详情、实拍图片和房东信息。
- 租房流程乱:线下的看房、签约、缴费记录容易扯皮,系统需要用状态机把“发布房源—申请看房—签约—入住—退租”这条链路管起来。
- 信息不透明:房东资质、房屋是否已出租、租期是否冲突,这些在传统租房平台上经常出现“图上没房、到店加价”的问题,系统要通过数据库约束和状态流转去规避。
再往细了拆,整个系统的功能模块大概分成四块:用户管理模块(注册、登录、身份认证、个人信息)、房源管理模块(发布、编辑、上下架、条件检索)、租房流程模块(看房申请、签约、退租)、后台管理模块(用户审核、房源审核、数据统计)。
这套功能拆出来之后,你会发现它跟市面上的商业租房平台(自如、贝壳)的核心逻辑是一致的,只是规模小得多。对毕业设计来说,这个规模刚好合适——既不是一个CRUD空壳,也不会复杂到半年做不完。
1.2 为什么选Spring Boot 2.7.18而不是3.x
技术选型这块我多说几句。网上关于Spring Boot版本的选择吵得挺厉害,尤其是Spring Boot 3.x发布之后,很多教程都在推新版本。但作为毕业设计,我强烈建议你选Spring Boot 2.7.18,这是我的核心推荐。
为什么?三个原因。
第一,JDK版本兼容性。Spring Boot 3.x强制要求JDK 17以上,而很多学校的课程教学还停留在JDK 8,实验室机器上装的是JDK 8,部分老旧的数据库驱动(比如某些学校的Oracle课程用的ojdbc6)也不兼容JDK 17。用2.7.18搭配JDK 8,是最稳的组合,不会在环境上卡壳。
第二,资料丰富程度。2.7.x是Spring Boot 2.x的最终版本,社区积累了大量踩坑案例。你遇到任何报错,搜索引擎一查基本都有答案。3.x的资料虽然也在积累,但对于一个要做半年以上、中间可能断断续续的毕业设计来说,稳定的资料库比尝鲜重要得多。
第三,跟后续课程和面试的衔接。很多学校的Java课程设计、企业级框架课程都是用Spring Boot 2.x讲的,面试时你写“熟悉Spring Boot 2.7.x”比写“了解Spring Boot 3.x新特性”更能经得起追问,因为你真的有大量实操经验。
顺带解释一下Spring Boot的自动装配原理,因为面试必问。Spring Boot核心的@SpringBootApplication注解是一个组合注解,它包含了@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan。真正起作用的是@EnableAutoConfiguration,它通过AutoConfigurationImportSelector这个类去读取META-INF/spring.factories文件(2.7.x版本)或META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件(3.x版本),把里面列出的所有自动配置类都加载到IoC容器中,再通过@ConditionalOnClass、@ConditionalOnProperty等条件注解判断,只实例化当前环境需要的Bean。
这么说有点抽象,我打个比方:自动配置就像一家自助餐厅,菜单上列了几十道菜,但厨师只做你选了的那几道。条件注解就是菜单上的勾选项——你引入了spring-boot-starter-web,相当于勾了“做一份Web应用”,于是相关的DispatcherServlet、Tomcat容器就自动配置出来了;你没引入MySQL驱动,那DataSource相关配置就自动跳过。
1.3 技术选型的其他细节:ORM、数据库、前端框架
确定Spring Boot之后,周边配套的技术选型同样重要。我的推荐组合是:
| 技术组件 | 推荐选型 | 选择理由 |
|---|---|---|
| ORM框架 | MyBatis Plus | 单表CRUD不用写SQL,内置分页插件,同时保留原生SQL能力做复杂查询 |
| 数据库 | MySQL 8.0 | 稳定、免费、资料多,学校机房和云服务器都能轻松部署 |
| 前端框架 | Vue 3 + Element Plus | 组件丰富,表格表单直接拿来用,前后端分离模式更贴近企业实际开发 |
| 鉴权方案 | JWT + Spring Boot拦截器 | 无状态、不用学Spring Security那一大堆过滤器链,毕业设计够用且好讲清楚 |
| 接口文档 | Knife4j(Swagger增强) | 自动生成接口文档,写论文时需要截图接口测试过程很方便 |
这里特别提醒一个点:不要一上来就堆技术。我见过不少同学把Redis、RabbitMQ、ElasticSearch一股脑全塞进系统,结果答辩时被老师问得哑口无言。毕业设计的关键不是用了多少技术,而是你清楚知道每个技术在系统里解决了什么具体问题。比如这个租房系统里,Redis可以做验证码缓存和热门房源缓存,这个我后面会讲;但如果你说不清楚“为什么这里非要用Redis,不用行不行”,那就别用,删掉它,系统依然成立。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 数据库设计与核心表结构规划
2.1 从业务场景倒推:我们需要哪些数据表
数据库设计是毕业设计中最能体现“设计能力”的环节。很多同学的数据库建表就是凭感觉,想到哪建到哪,结果后面写代码时发现字段不够用,或者表之间关联关系混乱,改起来非常痛苦。
正确做法是从业务场景倒推。你把系统的核心流程走一遍:学生注册登录→搜索房源→浏览详情→提交看房申请→房东同意→线下看房→线上签约→生成合同→缴费入住→退租。每一步会产生什么数据、需要记录什么字段,把这些都列出来,表结构就自然出来了。
我的核心表清单如下:
- 用户表(
user):承载所有角色的登录账号,通过role字段区分学生、房东、管理员。 - 房东信息表(
landlord_info):只有房东角色才有的扩展信息(身份证号、联系电话、信用评分),与学生用户冗余在user表不同。 - 房源表(
house):核心业务表,记录房源标题、描述、区域、地址、户型、面积、租金、押金、状态。 - 房源图片表(
house_image):一个房源对应多张图片,独立成表方便管理和展示。 - 收藏表(
favorite):学生收藏房源,记录用户ID和房源ID,联合唯一索引防止重复收藏。 - 看房申请表(
visit_apply):学生提交看房申请,包含申请状态(待确认/已同意/已拒绝/已取消)。 - 订单表(
rent_order):签约产生的订单,包含租期起止、月租金、押金、总金额、状态。 - 合同表(
contract):订单确认后生成合同,存储合同编号、签订时间、条款内容。 - 留言反馈表(
feedback):学生对房源或平台的留言,管理员可查看处理。
为什么把订单和合同拆成两张表?因为订单是“交易事件”,合同是“法律文件”,它们的生命周期不同。订单在支付完成前可以被取消,合同一旦生成就不允许随意修改,这份数据上的克制,就是数据库设计经验的体现。
2.2 关键表核心字段设计:房子表与订单表
拿房源表具体说一下字段设计。这是我实际用过的建表方案,关键字段都标了注释:
sql复制CREATE TABLE `house` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '房源ID',
`landlord_id` bigint(20) NOT NULL COMMENT '房东用户ID',
`title` varchar(100) NOT NULL COMMENT '房源标题',
`description` text COMMENT '房源描述',
`province` varchar(50) DEFAULT NULL COMMENT '省',
`city` varchar(50) NOT NULL COMMENT '市',
`district` varchar(50) NOT NULL COMMENT '区',
`address` varchar(200) NOT NULL COMMENT '详细地址',
`house_type` tinyint(4) NOT NULL COMMENT '户型:1-一室一厅 2-两室一厅 3-三室及以上 4-单间',
`area` decimal(10,2) NOT NULL COMMENT '面积(平方米)',
`rent` decimal(10,2) NOT NULL COMMENT '月租金(元)',
`deposit` decimal(10,2) DEFAULT NULL COMMENT '押金(元)',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态:0-待审核 1-已上架 2-已下架 3-已出租',
`verify_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '审核状态:0-待审核 1-通过 2-拒绝',
`view_count` int(11) NOT NULL DEFAULT '0' COMMENT '浏览次数',
`publish_time` datetime DEFAULT NULL COMMENT '发布时间',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_landlord_id` (`landlord_id`),
KEY `idx_district_rent` (`district`, `rent`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='房源表';
有几个设计心得值得分享:
第一,状态字段用tinyint存储,不用字符串。status存0、1、2、3,配合代码里的状态枚举类使用,这样数据库层面更省空间,代码层面通过HouseStatusEnum做可读性映射。
第二,尽量建联合索引。idx_district_rent这个索引就是针对“按区域+按价格筛选房源”这个高频查询场景建的。因为系统里最频繁的操作就是用户搜索房源,搜索条件通常是“XX区+租金3000以下”,这个联合索引能显著提升查询速度。
第三,冗余了view_count浏览计数字段。不要觉得冗余就是设计不好,在特定场景下,冗余字段能减少一次表关联查询。房源列表页要显示浏览次数,如果每次列表查询都要去统计表里算COUNT(*),数据一多性能就拉胯。直接用view_count字段,每次浏览时UPDATE house SET view_count = view_count + 1 WHERE id = ?,简单高效。
订单表的核心设计是状态机和金额字段:
sql复制CREATE TABLE `rent_order` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单ID',
`order_no` varchar(32) NOT NULL COMMENT '订单编号',
`house_id` bigint(20) NOT NULL COMMENT '房源ID',
`tenant_id` bigint(20) NOT NULL COMMENT '租客用户ID',
`landlord_id` bigint(20) NOT NULL COMMENT '房东用户ID',
`start_date` date NOT NULL COMMENT '合同开始日期',
`end_date` date NOT NULL COMMENT '合同结束日期',
`monthly_rent` decimal(10,2) NOT NULL COMMENT '月租金',
`deposit` decimal(10,2) NOT NULL COMMENT '押金',
`total_amount` decimal(10,2) NOT NULL COMMENT '总金额(押金+租金)',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态:0-待支付 1-已支付 2-已取消 3-已退租 4-已完成',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_order_no` (`order_no`),
KEY `idx_house_id` (`house_id`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSE
