随着房地产市场的蓬勃发展和人口流动性的增加,跨区域房屋租赁需求日益旺盛。传统租赁模式存在信息不对称、地域限制强、管理效率低等痛点,尤其对于拥有多城市房产资源的中介机构或个人房东而言,管理分散各地的房源成为巨大挑战。在此背景下,构建一个能够整合多城市资源、标准化租赁流程、提升信息匹配效率的数字化平台显得尤为重要。
本系统采用经典的SSM(Spring+SpringMVC+MyBatis)框架体系进行架构设计,结合MySQL数据库,实现了房源信息集中管理、跨城市检索、在线租赁申请、后台审核等核心功能。系统通过清晰的角色权限划分,为房东、租客和管理员三类用户提供差异化的服务界面和功能模块,有效解决了规模化、跨区域房屋租赁管理的技术难题。
系统架构与技术栈
系统采用典型的三层架构模式,实现了表现层、业务逻辑层和数据访问层的分离,保证了系统的可维护性和可扩展性。
表现层基于SpringMVC框架构建,采用前端控制器模式统一处理所有HTTP请求。通过注解驱动的方式配置控制器,大大简化了Web层的开发复杂度。结合JSP动态页面技术和Bootstrap前端框架,实现了响应式用户界面,确保在不同设备上都能获得良好的用户体验。
@Controller
@RequestMapping("/house")
public class HouseController {
@Autowired
private HouseService houseService;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public String getHouseList(@RequestParam(value = "cityId", required = false) Integer cityId,
@RequestParam(value = "page", defaultValue = "1") Integer pageNum,
Model model) {
PageInfo<House> pageInfo = houseService.getHousesByCity(cityId, pageNum, 10);
model.addAttribute("pageInfo", pageInfo);
model.addAttribute("cityId", cityId);
return "house/list";
}
}
业务逻辑层由Spring框架负责管理,通过依赖注入(DI)和控制反转(IoC)机制实现组件之间的松耦合。Spring的声明式事务管理确保了数据操作的一致性,特别是在复杂的租赁业务流程中,如房源发布、订单生成、合同签订等环节的事务完整性。
@Service
@Transactional
public class HouseServiceImpl implements HouseService {
@Autowired
private HouseMapper houseMapper;
@Override
public PageInfo<House> getHousesByCity(Integer cityId, Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<House> houses = houseMapper.selectByCityId(cityId);
return new PageInfo<>(houses);
}
@Override
public void publishHouse(House house) {
// 验证房源信息
validateHouseInfo(house);
// 设置默认状态
house.setStatus(HouseStatus.PENDING);
house.setCreateTime(new Date());
houseMapper.insert(house);
}
}
数据持久层采用MyBatis框架,通过XML映射文件灵活配置SQL语句,支持动态SQL生成,有效应对复杂的查询条件。MyBatis的缓存机制提升了系统性能,特别是在房源列表查询等高频操作场景下。
<!-- HouseMapper.xml -->
<mapper namespace="com.rental.mapper.HouseMapper">
<select id="selectByCityId" parameterType="int" resultType="House">
SELECT h.*, c.city_name
FROM house h
LEFT JOIN city c ON h.city_id = c.id
WHERE h.city_id = #{cityId}
AND h.status = 'APPROVED'
ORDER BY h.create_time DESC
</select>
<insert id="insert" parameterType="House" useGeneratedKeys="true" keyProperty="id">
INSERT INTO house (title, description, city_id, address, price,
area, room_count, landlord_id, status, create_time)
VALUES (#{title}, #{description}, #{cityId}, #{address}, #{price},
#{area}, #{room_count}, #{landlordId}, #{status}, #{createTime})
</insert>
</xml>
数据库设计亮点分析
系统数据库设计充分考虑了多城市房屋租赁的业务特点,通过合理的表结构设计和关联关系,支持高效的数据管理和复杂的业务查询。
城市表设计
城市表作为系统的核心基础数据表,采用层次化结构设计,支持省市区的三级联动,为多城市房源管理提供数据基础。
CREATE TABLE city (
id INT PRIMARY KEY AUTO_INCREMENT,
city_name VARCHAR(50) NOT NULL COMMENT '城市名称',
parent_id INT DEFAULT NULL COMMENT '父级城市ID',
level TINYINT NOT NULL COMMENT '城市级别:1-省/直辖市,2-市,3-区/县',
sort_order INT DEFAULT 0 COMMENT '排序字段',
status TINYINT DEFAULT 1 COMMENT '状态:0-禁用,1-启用',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_parent_id (parent_id),
INDEX idx_level (level)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='城市信息表';
该表设计的亮点在于:
- 层次化结构:通过parent_id字段实现城市层级关系,支持从省份到区县的多级查询
- 状态管理:status字段控制城市是否可用,便于系统扩展时动态管理城市数据
- 排序支持:sort_order字段确保城市列表展示的有序性
房源表设计
房源表是系统的核心业务表,设计上充分考虑了房屋租赁的业务特性和查询性能需求。
CREATE TABLE house (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(100) NOT NULL COMMENT '房源标题',
description TEXT COMMENT '房源描述',
city_id INT NOT NULL COMMENT '所在城市ID',
address VARCHAR(200) NOT NULL COMMENT '详细地址',
price DECIMAL(10,2) NOT NULL COMMENT '月租金',
area DECIMAL(6,2) NOT NULL COMMENT '房屋面积',
room_count TINYINT NOT NULL COMMENT '房间数量',
landlord_id INT NOT NULL COMMENT '房东ID',
status ENUM('PENDING','APPROVED','REJECTED','RENTED') DEFAULT 'PENDING' COMMENT '房源状态',
cover_image VARCHAR(200) COMMENT '封面图片',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_city_id (city_id),
INDEX idx_landlord_id (landlord_id),
INDEX idx_status (status),
INDEX idx_price (price),
FOREIGN KEY (city_id) REFERENCES city(id),
FOREIGN KEY (landlord_id) REFERENCES user(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='房源信息表';
该表设计的创新点包括:
- 状态机设计:使用ENUM类型明确定义房源生命周期状态,确保状态流转的规范性
- 空间数据优化:通过面积、房间数等字段支持多维度的房源筛选
- 外键约束:确保数据完整性,防止脏数据的产生
租赁订单表设计
租赁订单表记录了完整的租赁业务流程,设计上注重事务完整性和查询效率。
CREATE TABLE rental_order (
id INT PRIMARY KEY AUTO_INCREMENT,
house_id INT NOT NULL COMMENT '房源ID',
tenant_id INT NOT NULL COMMENT '租客ID',
order_no VARCHAR(32) NOT NULL UNIQUE COMMENT '订单编号',
total_amount DECIMAL(10,2) NOT NULL COMMENT '订单总金额',
lease_months INT NOT NULL COMMENT '租赁月数',
start_date DATE NOT NULL COMMENT '租赁开始日期',
end_date DATE NOT NULL COMMENT '租赁结束日期',
status ENUM('PENDING','CONFIRMED','PAID','COMPLETED','CANCELLED') DEFAULT 'PENDING',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_house_id (house_id),
INDEX idx_tenant_id (tenant_id),
INDEX idx_order_no (order_no),
INDEX idx_status (status),
FOREIGN KEY (house_id) REFERENCES house(id),
FOREIGN KEY (tenant_id) REFERENCES user(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租赁订单表';
核心功能模块深度解析
多城市房源检索与筛选
系统实现了高效的多城市房源检索功能,用户可以根据目标城市、租金范围、房型条件等多个维度进行精准筛选。前端采用Ajax异步加载技术,提升用户体验。

检索功能的实现涉及复杂的SQL查询构建,MyBatis的动态SQL特性在此发挥了重要作用:
<select id="selectHousesByCondition" parameterType="HouseQueryCondition" resultType="HouseVO">
SELECT h.*, c.city_name, u.username as landlord_name
FROM house h
LEFT JOIN city c ON h.city_id = c.id
LEFT JOIN user u ON h.landlord_id = u.id
WHERE h.status = 'APPROVED'
<if test="cityId != null">
AND h.city_id = #{cityId}
</if>
<if test="minPrice != null">
AND h.price >= #{minPrice}
</if>
<if test="maxPrice != null">
AND h.price <= #{maxPrice}
</if>
<if test="minArea != null">
AND h.area >= #{minArea}
</if>
<if test="roomCount != null">
AND h.room_count = #{roomCount}
</if>
<if test="keywords != null and keywords != ''">
AND (h.title LIKE CONCAT('%', #{keywords}, '%')
OR h.description LIKE CONCAT('%', #{keywords}, '%'))
</if>
ORDER BY
<choose>
<when test="sortType == 'price_asc'">h.price ASC</when>
<when test="sortType == 'price_desc'">h.price DESC</when>
<when test="sortType == 'time_desc'">h.create_time DESC</when>
<otherwise>h.create_time DESC</otherwise>
</choose>
</select>
对应的Java服务层代码实现了复杂的业务逻辑处理:
@Service
public class HouseSearchService {
public PageInfo<HouseVO> searchHouses(HouseQueryCondition condition, Integer pageNum, Integer pageSize) {
// 参数验证和预处理
validateSearchCondition(condition);
// 分页查询
PageHelper.startPage(pageNum, pageSize);
List<HouseVO> houses = houseMapper.selectHousesByCondition(condition);
// 数据后处理
processHouseImages(houses);
calculateDistanceIfNeeded(houses, condition.getUserLocation());
return new PageInfo<>(houses);
}
private void validateSearchCondition(HouseQueryCondition condition) {
if (condition.getMinPrice() != null && condition.getMaxPrice() != null) {
if (condition.getMinPrice() > condition.getMaxPrice()) {
throw new BusinessException("价格区间设置错误");
}
}
// 其他验证逻辑...
}
}
房源发布与审核流程
房东用户可以发布房源信息,系统通过工作流引擎管理房源的审核流程,确保房源信息的真实性和合规性。

房源发布功能涉及文件上传、数据验证、事务处理等多个技术要点:
@Controller
@RequestMapping("/landlord")
public class LandlordHouseController {
@PostMapping("/publish")
@ResponseBody
public ResponseEntity<?> publishHouse(
@Valid @ModelAttribute HousePublishRequest request,
BindingResult bindingResult,
@RequestParam("images") MultipartFile[] images) {
if (bindingResult.hasErrors()) {
return ResponseEntity.badRequest().body("参数验证失败");
}
try {
// 处理图片上传
List<String> imageUrls = new ArrayList<>();
for (MultipartFile image : images) {
if (!image.isEmpty()) {
String imageUrl = fileService.uploadImage(image);
imageUrls.add(imageUrl);
}
}
// 保存房源信息
House house = convertToHouse(request);
house.setImages(imageUrls);
houseService.publishHouse(house);
return ResponseEntity.ok("房源发布成功,等待审核");
} catch (Exception e) {
log.error("房源发布失败", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("发布失败,请稍后重试");
}
}
}
管理员审核功能实现了批量操作和状态跟踪:

@Service
@Transactional
public class HouseAuditService {
public void batchApproveHouses(List<Integer> houseIds, Integer adminId, String auditRemark) {
if (houseIds == null || houseIds.isEmpty()) {
throw new BusinessException("请选择要审核的房源");
}
for (Integer houseId : houseIds) {
House house = houseMapper.selectById(houseId);
if (house != null && house.getStatus() == HouseStatus.PENDING) {
// 更新房源状态
house.setStatus(HouseStatus.APPROVED);
house.setUpdateTime(new Date());
houseMapper.updateStatus(house);
// 记录审核日志
AuditLog auditLog = new AuditLog();
auditLog.setHouseId(houseId);
auditLog.setAdminId(adminId);
auditLog.setAction(AuditAction.APPROVE);
auditLog.setRemark(auditRemark);
auditLog.setCreateTime(new Date());
auditLogMapper.insert(auditLog);
// 发送通知给房东
notificationService.sendHouseApprovedNotification(house.getLandlordId(), houseId);
}
}
}
}
租赁订单管理
系统实现了完整的租赁业务流程,包括订单生成、支付处理、合同管理等功能模块。

订单生成服务处理复杂的业务规则验证:
@Service
@Transactional
public class OrderService {
public RentalOrder createRentalOrder(OrderCreateRequest request) {
// 验证房源可用性
House house = houseMapper.selectById(request.getHouseId());
if (house == null || house.getStatus() != HouseStatus.APPROVED) {
throw new BusinessException("房源不存在或不可租");
}
// 验证租赁时间冲突
if (isRentalPeriodConflict(request.getHouseId(), request.getStartDate(), request.getEndDate())) {
throw new BusinessException("该时间段房源已被预订");
}
// 计算租金
BigDecimal totalAmount = calculateTotalAmount(house.getPrice(),
request.getLeaseMonths(),
request.getStartDate(),
request.getEndDate());
// 生成订单
RentalOrder order = new RentalOrder();
order.setOrderNo(generateOrderNo());
order.setHouseId(request.getHouseId());
order.setTenantId(request.getTenantId());
order.setTotalAmount(totalAmount);
order.setLeaseMonths(request.getLeaseMonths());
order.setStartDate(request.getStartDate());
order.setEndDate(request.getEndDate());
order.setStatus(OrderStatus.PENDING);
orderMapper.insert(order);
// 更新房源状态为已预订
house.setStatus(HouseStatus.RENTED);
houseMapper.updateStatus(house);
return order;
}
private String generateOrderNo() {
return "RO" + System.currentTimeMillis() +
String.format("%04d", new Random().nextInt(10000));
}
}
用户权限管理与安全控制
系统采用基于角色的访问控制(RBAC)模型,实现精细化的权限管理。

Spring Security配置实现安全控制:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/landlord/**").hasAnyRole("LANDLORD", "ADMIN")
.antMatchers("/tenant/**").hasAnyRole("TENANT", "ADMIN")
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/dashboard")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.csrf().disable();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
实体模型与业务逻辑
系统核心实体模型设计体现了房屋租赁业务的复杂性,通过面向对象的设计原则实现了高内聚、低耦合的架构。
用户实体模型
用户实体采用继承体系设计,支持不同类型的用户角色:
@Entity
@Table(name = "user")
@Inheritance(strategy = InheritanceType.JOINED)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(unique = true, nullable = false)
private String username;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String email;
@Enumerated(EnumType.STRING)
private UserRole role;
private String phone;
private Date createTime;
private Date updateTime;
private Boolean enabled = true;
// 省略getter/setter方法
}
@Entity
@Table(name = "landlord")
@PrimaryKeyJoinColumn(name = "user_id")
public class Landlord extends User {
private String realName;
private String idCard