基于SSM框架的多城市房屋租赁管理平台 - 源码深度解析

JavaJavaScriptMavenHTMLCSSSSM框架MySQL
2026-03-284 浏览

文章摘要

本项目是一款基于SSM(Spring+SpringMVC+MyBatis)框架构建的多城市房屋租赁管理平台,旨在解决传统房屋租赁市场中信息分散、跨区域管理困难、业务流程繁琐等核心痛点。平台通过整合不同城市的房源信息,为房东和租客提供一站式的租赁服务,有效提升信息匹配效率,降低交易成本,实现租赁流程的...

随着房地产市场的蓬勃发展和人口流动性的增加,跨区域房屋租赁需求日益旺盛。传统租赁模式存在信息不对称、地域限制强、管理效率低等痛点,尤其对于拥有多城市房产资源的中介机构或个人房东而言,管理分散各地的房源成为巨大挑战。在此背景下,构建一个能够整合多城市资源、标准化租赁流程、提升信息匹配效率的数字化平台显得尤为重要。

本系统采用经典的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
本文关键词
SSM框架房屋租赁管理多城市房源SpringMVCMyBatis

上下篇

上一篇
没有更多文章
下一篇
没有更多文章