基于SSH框架的羽毛球馆预约管理系统 - 源码深度解析

JavaJavaScriptSSH框架HTMLCSSMySQLJSP+Servlet
2026-02-253 浏览

文章摘要

本系统基于经典的SSH(Struts2 + Spring + Hibernate)框架技术栈构建,旨在为羽毛球馆经营者提供一个高效、规范的数字化运营解决方案。其核心业务价值在于彻底解决了传统电话或现场预约方式带来的信息混乱、效率低下、易出错等管理痛点。通过将场馆资源、预约订单和用户信息进行系统化整合...

在体育产业数字化浪潮的背景下,传统羽毛球馆的运营模式面临着效率瓶颈。手工登记预约、电话确认场地、纸质记录财务等方式不仅容易出错,更难以应对高峰时段的并发需求。针对这一痛点,我们设计并实现了基于SSH技术栈的“羽翼”智能场馆管理系统,通过全流程数字化管理提升场馆运营效率。

系统采用经典的三层架构模式,表现层使用Struts2框架处理用户请求和页面跳转,业务层通过Spring框架实现依赖注入和事务管理,持久层则基于Hibernate完成对象关系映射。这种分层架构确保了系统的高内聚低耦合特性,为后续功能扩展和维护提供了良好基础。

数据库架构设计精要

系统的数据模型设计充分考虑了羽毛球馆业务的复杂性,共包含11张核心数据表。其中场地预约表的设计尤为关键,它承担着协调场馆资源的核心使命。

CREATE TABLE reservation (
    id INT PRIMARY KEY AUTO_INCREMENT,
    court_id INT NOT NULL,
    user_id INT NOT NULL,
    start_time DATETIME NOT NULL,
    end_time DATETIME NOT NULL,
    status ENUM('pending', 'confirmed', 'cancelled') DEFAULT 'pending',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    total_amount DECIMAL(10,2),
    FOREIGN KEY (court_id) REFERENCES court(id),
    FOREIGN KEY (user_id) REFERENCES user(id),
    INDEX idx_court_time (court_id, start_time, end_time)
);

该表通过外键关联场地和用户实体,并建立了复合索引优化时间冲突查询性能。status字段采用枚举类型确保数据一致性,created_at时间戳为后续数据分析提供支持。

用户权限表的设计体现了系统的多角色管理特性:

CREATE TABLE user (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    role ENUM('admin', 'cashier', 'member') NOT NULL,
    phone VARCHAR(20),
    balance DECIMAL(10,2) DEFAULT 0.00,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    last_login DATETIME
);

通过role字段实现三级权限控制,balance字段支持会员预充值功能,last_login记录用户活跃度,为运营决策提供数据支持。

核心业务逻辑实现

1. 场地预约冲突检测机制 预约功能的核心在于解决时间冲突问题,系统通过Hibernate实现高效的冲突检测:

public class ReservationServiceImpl implements ReservationService {
    
    @Autowired
    private ReservationDAO reservationDAO;
    
    @Transactional
    public boolean checkTimeConflict(Integer courtId, Date startTime, Date endTime) {
        String hql = "SELECT COUNT(r) FROM Reservation r WHERE r.court.id = :courtId " +
                    "AND r.status != 'cancelled' " +
                    "AND ((r.startTime BETWEEN :startTime AND :endTime) " +
                    "OR (r.endTime BETWEEN :startTime AND :endTime) " +
                    "OR (r.startTime <= :startTime AND r.endTime >= :endTime))";
        
        Long count = (Long) reservationDAO.createQuery(hql)
            .setParameter("courtId", courtId)
            .setParameter("startTime", startTime)
            .setParameter("endTime", endTime)
            .uniqueResult();
        
        return count > 0;
    }
}

该方法通过HQL查询实现了精确的时间段重叠检测,确保同一场地在相同时段内只能有一个有效预约。

场地预约界面

2. 多角色权限控制体系 系统通过Struts2拦截器实现细粒度的权限控制:

<package name="secure" extends="struts-default" namespace="/admin">
    <interceptors>
        <interceptor name="authInterceptor" 
                    class="com.maancode.interceptor.AuthInterceptor"/>
        <interceptor-stack name="secureStack">
            <interceptor-ref name="authInterceptor"/>
            <interceptor-ref name="defaultStack"/>
        </interceptor-stack>
    </interceptors>
    
    <default-interceptor-ref name="secureStack"/>
    
    <action name="manageCourts" class="courtManagementAction">
        <result>/admin/court_management.jsp</result>
        <result name="error">/error.jsp</result>
    </action>
</package>

拦截器核心验证逻辑:

public class AuthInterceptor extends AbstractInterceptor {
    
    public String intercept(ActionInvocation invocation) throws Exception {
        Map<String, Object> session = invocation.getInvocationContext().getSession();
        User user = (User) session.get("currentUser");
        
        if (user == null) {
            return "login";
        }
        
        String actionName = invocation.getProxy().getActionName();
        if (!hasPermission(user.getRole(), actionName)) {
            return "noPermission";
        }
        
        return invocation.invoke();
    }
    
    private boolean hasPermission(Role role, String action) {
        // 基于角色的权限验证逻辑
        return permissionService.checkPermission(role, action);
    }
}

3. 预约业务流程整合 完整的预约流程涉及多个服务组件的协同工作:

public class BookingAction extends ActionSupport {
    private Reservation reservation;
    private String message;
    
    public String execute() {
        try {
            // 1. 验证用户身份
            User user = getCurrentUser();
            if (user == null) return "login";
            
            // 2. 检查时间冲突
            if (reservationService.checkTimeConflict(
                reservation.getCourt().getId(),
                reservation.getStartTime(),
                reservation.getEndTime())) {
                message = "该时间段已被预约";
                return ERROR;
            }
            
            // 3. 计算费用
            BigDecimal amount = pricingService.calculateAmount(
                reservation.getStartTime(),
                reservation.getEndTime(),
                reservation.getCourt().getType());
            
            // 4. 创建预约记录
            reservation.setUser(user);
            reservation.setTotalAmount(amount);
            reservationService.createReservation(reservation);
            
            message = "预约成功";
            return SUCCESS;
            
        } catch (Exception e) {
            message = "系统错误,请稍后重试";
            return ERROR;
        }
    }
}

订单管理界面

实体关系映射策略

Hibernate实体映射采用了优化的关联策略,确保数据一致性和查询性能:

@Entity
@Table(name = "court")
public class Court {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    
    @Column(name = "name", nullable = false, length = 100)
    private String name;
    
    @Enumerated(EnumType.STRING)
    @Column(name = "type")
    private CourtType type;
    
    @Column(name = "hourly_rate")
    private BigDecimal hourlyRate;
    
    @OneToMany(mappedBy = "court", fetch = FetchType.LAZY)
    private Set<Reservation> reservations;
    
    // 省略getter/setter方法
}

@Entity
@Table(name = "reservation")
public class Reservation {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "court_id")
    private Court court;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "start_time")
    private Date startTime;
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "end_time")
    private Date endTime;
    
    // 省略其他字段和方法
}

通过LAZY加载策略优化性能,@Enumerated注解确保枚举类型在数据库中的存储一致性。

事务管理与数据一致性

Spring的声明式事务管理确保了复杂业务操作的数据一致性:

<bean id="transactionManager" 
      class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="create*" propagation="REQUIRED"/>
        <tx:method name="update*" propagation="REQUIRED"/>
        <tx:method name="delete*" propagation="REQUIRED"/>
        <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:advisor advice-ref="txAdvice" 
                pointcut="execution(* com.maancode.service.*Service.*(..))"/>
</aop:config>

服务层方法的事务控制:

@Service
@Transactional
public class ReservationServiceImpl implements ReservationService {
    
    @Transactional(propagation = Propagation.REQUIRED)
    public void cancelReservation(Integer reservationId) {
        try {
            Reservation reservation = reservationDAO.findById(reservationId);
            reservation.setStatus(ReservationStatus.CANCELLED);
            reservationDAO.update(reservation);
            
            // 记录取消日志
            auditService.logCancelOperation(reservation);
            
        } catch (Exception e) {
            throw new RuntimeException("取消预约失败", e);
        }
    }
}

会员管理界面

系统优化与扩展方向

1. 性能优化策略

  • 查询缓存优化:对场地信息等静态数据启用Hibernate二级缓存
  • 连接池配置:通过C3P0连接池管理数据库连接,提高并发处理能力
  • 分页查询:对大数量级数据实现分页加载,减轻数据库压力
public class PaginationUtil {
    public static Pageable createPageRequest(int page, int size, String sortField) {
        return PageRequest.of(page - 1, size, Sort.by(sortField).ascending());
    }
}

2. 安全增强方案

  • 密码加密存储:采用BCrypt算法对用户密码进行加密
  • SQL注入防护:使用Hibernate参数化查询避免SQL注入风险
  • XSS攻击防护:对用户输入进行严格的过滤和转义处理

3. 功能扩展规划

  • 移动端适配:开发响应式界面支持移动设备访问
  • 微信小程序集成:通过API接口与微信小程序对接
  • 数据分析模块:基于预约数据生成经营分析报表
  • 智能推荐:根据用户历史预约推荐合适时段和场地

场地管理界面

技术实现特色

系统在技术实现上展现了多个亮点。首先,通过Hibernate的Criteria API实现了动态查询构建,支持复杂的多条件筛选:

public List<Reservation> findReservations(ReservationQuery query) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Reservation> cq = cb.createQuery(Reservation.class);
    Root<Reservation> root = cq.from(Reservation.class);
    
    List<Predicate> predicates = new ArrayList<>();
    
    if (query.getCourtId() != null) {
        predicates.add(cb.equal(root.get("court").get("id"), query.getCourtId()));
    }
    
    if (query.getStartDate() != null) {
        predicates.add(cb.greaterThanOrEqualTo(root.get("startTime"), query.getStartDate()));
    }
    
    if (query.getEndDate() != null) {
        predicates.add(cb.lessThanOrEqualTo(root.get("endTime"), query.getEndDate()));
    }
    
    cq.where(predicates.toArray(new Predicate[0]));
    return entityManager.createQuery(cq).getResultList();
}

其次,系统实现了完整的异常处理机制,通过自定义异常类细化错误处理:

public class BusinessException extends RuntimeException {
    private ErrorCode errorCode;
    
    public BusinessException(ErrorCode errorCode, String message) {
        super(message);
        this.errorCode = errorCode;
    }
    
    // 异常处理统一入口
    @ExceptionHandler(BusinessException.class)
    public ModelAndView handleBusinessException(BusinessException ex) {
        ModelAndView mav = new ModelAndView("error");
        mav.addObject("errorCode", ex.getErrorCode());
        mav.addObject("message", ex.getMessage());
        return mav;
    }
}

系统还实现了灵活的价格策略管理,支持不同时段、不同类型场地的差异化定价:

public class PricingStrategy {
    public BigDecimal calculatePrice(CourtType type, Date startTime, Date endTime) {
        // 基础价格计算
        BigDecimal basePrice = getBasePrice(type);
        
        // 时段系数调整
        double timeFactor = getTimeFactor(startTime);
        
        // 时长计算
        long hours = calculateDurationInHours(startTime, endTime);
        
        return basePrice.multiply(BigDecimal.valueOf(timeFactor * hours));
    }
}

这套“羽翼”智能场馆管理系统通过严谨的技术架构设计和精细的业务逻辑实现,为羽毛球馆运营提供了完整的数字化解决方案。系统不仅解决了当前的管理痛点,更为未来的功能扩展和技术升级预留了充分的空间。

本文关键词
SSH框架羽毛球馆预约管理系统源码解析数据库设计业务逻辑

上下篇

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