基于SSH架构的高校宿舍信息管理系统 - 源码深度解析

JavaJavaScriptSSH框架HTMLCSSMySQLJSP+Servlet
2026-03-212 浏览

文章摘要

本项目基于经典的SSH(Struts2 + Spring + Hibernate)架构设计,旨在为高校后勤部门提供一体化的宿舍信息管理解决方案。系统核心解决了传统手工或半自动化管理模式下的数据分散、更新滞后、查询效率低下等痛点,通过集中化数据管理、标准化业务流程,显著提升宿舍分配、调整、报修及学生信...

在高校后勤管理领域,宿舍资源的高效、精准管理一直是提升校园服务水平的关键环节。传统依赖纸质档案或零散Excel表格的管理方式,不仅效率低下,且极易出现数据不一致、信息更新滞后等问题。为此,我们设计并实现了一套基于SSH(Struts2 + Spring + Hibernate)架构的“高校智慧宿管平台”,旨在通过信息化手段,实现宿舍分配、调整、报修及学生信息维护的全流程数字化管理。

系统采用经典的三层架构设计,将表现层、业务逻辑层和数据持久层清晰分离。表现层使用Struts2框架处理用户请求与页面跳转,通过配置struts.xml文件定义Action映射关系,确保请求能够准确路由至对应的业务处理方法。业务逻辑层由Spring框架的IoC容器统一管理,各Service组件通过依赖注入方式解耦,同时利用Spring的声明式事务管理(@Transactional)保障数据操作的原子性与一致性。数据持久层则基于Hibernate实现对象关系映射(ORM),将Java实体类与数据库表结构关联,通过HQL(Hibernate Query Language)或Criteria API进行数据查询,有效简化了JDBC的繁琐操作,并借助一级缓存、二级缓存机制提升系统性能。


数据库设计亮点

系统的数据模型围绕宿舍管理的核心实体构建,共设计8张数据表。以下重点分析dormitory(宿舍房间)和student(学生信息)两张核心表的结构设计。

1. 宿舍房间表(dormitory)设计

CREATE TABLE `dormitory` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `building_id` int(11) NOT NULL COMMENT '所属楼宇ID',
  `room_number` varchar(20) NOT NULL COMMENT '房间号',
  `bed_count` int(11) NOT NULL DEFAULT 4 COMMENT '床位总数',
  `occupied_bed_count` int(11) NOT NULL DEFAULT 0 COMMENT '已占用床位数',
  `status` tinyint(4) NOT NULL DEFAULT 1 COMMENT '状态:1-可入住,2-已满员,3-维修中',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_building_room` (`building_id`,`room_number`),
  KEY `idx_status` (`status`),
  CONSTRAINT `fk_dormitory_building` FOREIGN KEY (`building_id`) REFERENCES `building` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='宿舍房间表';

该表设计体现了以下技术考量:

  • 唯一性约束:通过UNIQUE KEY uk_building_room (building_id, room_number)确保同一栋楼内房间号唯一,从数据库层面杜绝重复房间录入。
  • 状态机设计status字段使用TINYINT类型定义房间的三种状态,便于业务逻辑中快速筛选可用房间(如新生分配时只查询status=1的房间)。
  • 冗余字段优化查询occupied_bed_count作为冗余字段,实时记录当前入住人数。相较于每次通过COUNT(*)关联查询bed表,该设计显著提升了“查询楼栋空余床位”等高频操作的性能。
  • 外键约束:通过FOREIGN KEY关联building表,确保数据引用完整性,避免出现“幽灵房间”(不属于任何楼栋的房间)。

2. 学生信息表(student)设计

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `student_number` varchar(20) NOT NULL COMMENT '学号',
  `name` varchar(50) NOT NULL COMMENT '姓名',
  `gender` tinyint(4) NOT NULL COMMENT '性别:1-男,2-女',
  `class_id` int(11) NOT NULL COMMENT '班级ID',
  `bed_id` int(11) DEFAULT NULL COMMENT '分配的床位ID',
  `check_in_date` date DEFAULT NULL COMMENT '入住日期',
  `check_out_date` date DEFAULT NULL COMMENT '退宿日期',
  `is_checked_out` tinyint(1) DEFAULT '0' COMMENT '是否已退宿:0-否,1-是',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_student_number` (`student_number`),
  UNIQUE KEY `uk_bed_id` (`bed_id`),
  KEY `idx_class` (`class_id`),
  KEY `idx_check_status` (`is_checked_out`),
  CONSTRAINT `fk_student_bed` FOREIGN KEY (`bed_id`) REFERENCES `bed` (`id`),
  CONSTRAINT `fk_student_class` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生信息表';

该表的精妙之处在于:

  • 软删除设计:通过is_checked_out标志位实现软删除,而非物理删除记录。这完整保留了学生的住宿历史,便于后续审计或生成报表(如年度住宿率统计)。
  • 床位分配约束bed_id字段设置唯一约束,确保一个床位在同一时间只能分配给一名学生,从根本上避免了分配冲突。
  • 多维度索引:针对class_idis_checked_out建立索引,极大优化了“按班级查询在宿学生”、“批量处理退宿学生”等业务场景的查询效率。

核心功能实现与代码解析

1. 宿舍自动分配算法

新生入学时,系统需根据性别、院系等条件自动分配宿舍。该功能由DormitoryAllocationService实现,其核心算法如下:

@Service
@Transactional
public class DormitoryAllocationService {
    
    @Autowired
    private DormitoryDao dormitoryDao;
    @Autowired
    private StudentDao studentDao;
    
    /**
     * 自动分配宿舍
     * @param studentList 待分配的学生列表
     * @param gender 性别要求
     * @return 分配结果
     */
    public AllocationResult autoAllocate(List<Student> studentList, Integer gender) {
        AllocationResult result = new AllocationResult();
        // 1. 查询符合条件的空余宿舍(按楼栋、楼层排序)
        List<Dormitory> availableDorms = dormitoryDao.findAvailableDormitories(gender);
        
        for (Student student : studentList) {
            boolean allocated = false;
            for (Dormitory dorm : availableDorms) {
                // 2. 检查该宿舍是否还有空床位
                if (dorm.getOccupiedBedCount() < dorm.getBedCount()) {
                    // 3. 分配床位并更新状态
                    Bed allocatedBed = allocateBedToStudent(dorm, student);
                    student.setBedId(allocatedBed.getId());
                    student.setCheckInDate(new Date());
                    studentDao.update(student);
                    
                    // 4. 更新宿舍占用数
                    dorm.setOccupiedBedCount(dorm.getOccupiedBedCount() + 1);
                    if (dorm.getOccupiedBedCount().equals(dorm.getBedCount())) {
                        dorm.setStatus(DormitoryStatus.FULL);
                    }
                    dormitoryDao.update(dorm);
                    
                    result.addSuccess(student, dorm);
                    allocated = true;
                    break;
                }
            }
            if (!allocated) {
                result.addFailure(student, "无可用宿舍");
            }
        }
        return result;
    }
    
    private Bed allocateBedToStudent(Dormitory dorm, Student student) {
        // 简化逻辑:获取该宿舍第一个空闲床位
        Bed bed = bedDao.findFirstEmptyBedByDormitory(dorm.getId());
        bed.setStudentId(student.getId());
        bed.setStatus(BedStatus.OCCUPIED);
        bedDao.update(bed);
        return bed;
    }
}

该算法通过遍历可用宿舍列表,优先填充未满员的房间,确保房间使用率最大化。同时,利用@Transactional注解保证分配过程中学生信息更新、床位状态变更、宿舍占用数修改等多个数据库操作在一个事务内完成,避免出现数据不一致。

宿舍分配界面

2. 退宿审批流程

学生退宿需经过辅导员审批、楼管确认、系统归档多级流程。退宿核心逻辑在CheckOutService中实现:

@Service
public class CheckOutService {
    
    @Autowired
    private CheckOutApplyDao applyDao;
    @Autowired
    private StudentDao studentDao;
    @Autowired
    private BedDao bedDao;
    
    /**
     * 提交退宿申请
     */
    public void applyCheckOut(Integer studentId, String reason) {
        CheckOutApply apply = new CheckOutApply();
        apply.setStudentId(studentId);
        apply.setReason(reason);
        apply.setStatus(ApplyStatus.PENDING_REVIEW); // 初始状态:待辅导员审核
        apply.setApplyTime(new Date());
        applyDao.save(apply);
        
        // 发送通知给辅导员(此处可集成消息队列)
        notifyCounselor(apply);
    }
    
    /**
     * 审批退宿申请
     */
    @Transactional
    public void approveCheckOut(Integer applyId, Integer approverId, String comments) {
        CheckOutApply apply = applyDao.get(applyId);
        if (apply.getStatus() == ApplyStatus.PENDING_REVIEW) {
            // 辅导员审批通过,转楼管确认
            apply.setStatus(ApplyStatus.PENDING_CONFIRMATION);
            apply.setReviewerId(approverId);
            apply.setReviewTime(new Date());
            apply.setReviewComments(comments);
            applyDao.update(apply);
            notifyBuildingManager(apply);
        } else if (apply.getStatus() == ApplyStatus.PENDING_CONFIRMATION) {
            // 楼管确认,执行实际退宿操作
            performCheckOut(apply);
            apply.setConfirmerId(approverId);
            apply.setConfirmTime(new Date());
            apply.setStatus(ApplyStatus.COMPLETED);
            applyDao.update(apply);
        }
    }
    
    private void performCheckOut(CheckOutApply apply) {
        Student student = studentDao.get(apply.getStudentId());
        // 1. 清空学生床位信息
        Bed bed = bedDao.get(student.getBedId());
        bed.setStudentId(null);
        bed.setStatus(BedStatus.EMPTY);
        bedDao.update(bed);
        
        // 2. 更新学生退宿状态
        student.setBedId(null);
        student.setCheckOutDate(new Date());
        student.setIsCheckedOut(true);
        studentDao.update(student);
        
        // 3. 更新宿舍占用数
        Dormitory dorm = dormitoryDao.get(bed.getDormitoryId());
        dorm.setOccupiedBedCount(dorm.getOccupiedBedCount() - 1);
        if (dorm.getStatus() == DormitoryStatus.FULL) {
            dorm.setStatus(DormitoryStatus.AVAILABLE);
        }
        dormitoryDao.update(dorm);
    }
}

该流程通过状态机(ApplyStatus)驱动,每个环节的审批结果决定流程的下一走向,确保退宿操作规范有序。

退宿记录查询

3. 宿舍报修与跟踪

宿舍设施报修功能涉及报修提交、任务分配、维修进度跟踪等环节。核心实体关系及状态跟踪代码如下:

@Entity
@Table(name = "repair_application")
public class RepairApplication {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    
    @Column(name = "dormitory_id")
    private Integer dormitoryId;
    
    @Column(name = "description")
    private String description; // 报修描述
    
    @Column(name = "applicant_id")
    private Integer applicantId; // 申请人(学生或楼管)
    
    @Column(name = "status")
    private RepairStatus status; // 状态:待受理、维修中、已完成
    
    @Column(name = "assignee_id")
    private Integer assigneeId; // 指派给哪个维修工
    
    @Column(name = "apply_time")
    private Date applyTime;
    
    @Column(name = "complete_time")
    private Date completeTime;
    
    // 省略getter/setter
}

@Service
public class RepairTrackingService {
    
    /**
     * 更新维修进度
     */
    public void updateRepairProgress(Integer applicationId, RepairStatus newStatus, String remark) {
        RepairApplication application = repairAppDao.get(applicationId);
        application.setStatus(newStatus);
        if (newStatus == RepairStatus.COMPLETED) {
            application.setCompleteTime(new Date());
        }
        repairAppDao.update(application);
        
        // 记录维修日志
        RepairLog log = new RepairLog();
        log.setApplicationId(applicationId);
        log.setOperatorId(getCurrentUserId());
        log.setAction("状态更新: " + newStatus.getDescription());
        log.setRemark(remark);
        log.setOperateTime(new Date());
        repairLogDao.save(log);
        
        // 状态推送(如WebSocket通知申请人)
        pushStatusUpdate(application, newStatus);
    }
}

报修模块通过RepairApplication实体跟踪每次报修的全生命周期,并结合RepairLog记录所有状态变更历史,便于追溯责任与分析维修效率。

缺勤记录查询

4. 多条件组合查询

系统支持按楼栋、楼层、班级、学号等多维度组合查询学生住宿信息。该功能通过Hibernate的Criteria API动态构建查询条件:

@Repository
public class StudentDaoImpl extends BaseDaoImpl<Student> implements StudentDao {
    
    public List<Student> findStudentsByCriteria(StudentQueryCriteria criteria) {
        Criteria c = createCriteria();
        // 动态添加查询条件
        if (criteria.getBuildingId() != null) {
            c.createAlias("bed", "b")
             .createAlias("b.dormitory", "d")
             .add(Restrictions.eq("d.buildingId", criteria.getBuildingId()));
        }
        if (criteria.getClassId() != null) {
            c.add(Restrictions.eq("classId", criteria.getClassId()));
        }
        if (StringUtils.isNotBlank(criteria.getStudentNumber())) {
            c.add(Restrictions.like("studentNumber", criteria.getStudentNumber(), MatchMode.START));
        }
        if (criteria.getIsCheckedOut() != null) {
            c.add(Restrictions.eq("isCheckedOut", criteria.getIsCheckedOut()));
        }
        // 排序规则
        c.addOrder(Order.asc("classId"))
         .addOrder(Order.asc("studentNumber"));
        
        return c.list();
    }
}

该实现通过动态拼接查询条件,避免了编写大量重复的HQL语句,提高了代码的可维护性与扩展性。

学生管理界面


实体模型与ORM映射

系统通过Hibernate注解方式定义实体类及其关联关系,以下以DormitoryBed的一对多关系为例:

@Entity
@Table(name = "dormitory")
public class Dormitory {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    
    @Column(name = "building_id")
    private Integer buildingId;
    
    @Column(name = "room_number")
    private String roomNumber;
    
    // 与Bed实体的一对多关系
    @OneToMany(mappedBy = "dormitory", fetch = FetchType.LAZY)
    @Where(clause = "is_deleted = 0") // 软删除过滤
    private Set<Bed> beds = new HashSet<>();
    
    // 省略其他字段及getter/setter
}

@Entity
@Table(name = "bed")
public class Bed {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    
    @Column(name = "dormitory_id")
    private Integer dormitoryId;
    
    @Column(name = "bed_number")
    private String bedNumber;
    
    // 多对一关系
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "dormitory_id", insertable = false, updatable = false)
    private Dormitory dormitory;
    
    // 一对一关系(与学生)
    @OneToOne
    @JoinColumn(name = "student_id", referencedColumnName = "id")
    private Student student;
    
    // 省略其他字段
}

通过@OneToMany@ManyToOne注解,Hibernate自动维护了宿舍与床位之间的关联关系。配置fetch = FetchType.LAZY实现懒加载,仅在需要访问beds集合时才执行SQL查询,优化了性能。


功能展望与优化方向

  1. 移动端支持与微信小程序集成

    • 实现思路:开发基于Vue.js或React Native的移动端应用,通过RESTful API与后端交互。重点实现扫码报修(学生扫描宿舍门口二维码直接提交报修)、推送通知(审批结果、维修进度实时推送)、移动审批(辅导员、楼管手机端处理业务)等功能。
  2. 数据可视化与智能分析看板

    • 实现思路:集成ECharts或D3.js等可视化库,构建宿舍资源使用率热力图、报修类型统计、人员流动趋势分析等看板。后端通过定时任务聚合数据,提供JSON接口供前端渲染。
  3. 物联网设备集成与智能门锁管理

    • 实现思路:设计硬件接入层API,支持门锁状态监控、用电异常报警等。学生退宿后系统自动下发指令禁用门锁权限;归寝统计可通过门禁刷卡数据自动完成。
  4. 工作流引擎集成实现复杂审批可配置化

    • 实现思路:引入Activiti或Flowable工作流引擎,将宿舍调整、大型维修申请等复杂流程可视化配置。避免硬编码审批流程,提升系统对不同高校管理制度的适应性。
  5. 微服务架构改造以提升系统弹性

    • 实现思路:将单体应用拆分为宿舍管理、学生服务、报修服务、权限管理等独立微服务。通过
本文关键词
SSH架构高校宿舍管理信息管理系统源码解析数据库设计

上下篇

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