基于JSP+Servlet的酒店客房预订管理系统 - 源码深度解析

JavaJavaScriptMavenHTMLCSSMySQLJSP+Servlet
2026-03-184 浏览

文章摘要

本项目是一款基于JSP和Servlet技术栈构建的酒店客房预订管理系统,旨在为中小型酒店或民宿提供一站式的数字化运营解决方案。其核心业务价值在于解决了传统酒店依赖人工记录、电话预订带来的效率低下、信息不透明及易出错等痛点。系统通过将客房资源、预订流程和后台管理在线化,实现了业务闭环,有效降低了运营成...

在传统酒店行业数字化转型的浪潮中,一套高效、稳定的客房预订管理系统成为提升运营效率的关键。本系统采用经典的JSP+Servlet技术栈,构建了一个功能完备的酒店业务管理平台,实现了从客房管理、订单处理到后台运维的全流程数字化。

系统采用分层架构设计,严格遵循MVC模式。Servlet作为控制器层,负责请求分发和业务逻辑调度;JSP视图层通过EL表达式和JSTL标签库实现数据渲染;JavaBean模型层封装核心业务规则;数据持久层基于JDBC实现MySQL数据库操作。这种架构保证了代码的模块化和可维护性。

数据库设计深度解析

系统的数据库包含14张业务表,其中客房信息表(room)的设计尤为关键:

CREATE TABLE room (
    room_id INT PRIMARY KEY AUTO_INCREMENT,
    room_number VARCHAR(20) UNIQUE NOT NULL,
    room_type_id INT NOT NULL,
    room_status ENUM('空闲','已预订','已入住','维修中') DEFAULT '空闲',
    price DECIMAL(10,2) NOT NULL,
    description TEXT,
    FOREIGN KEY (room_type_id) REFERENCES room_type(type_id)
);

该表通过ENUM类型严格约束房态流转,使用DECIMAL类型确保金额计算的精确性。外键关联到房型表,实现数据规范化。

订单表(orders)的设计体现了复杂的业务逻辑:

CREATE TABLE orders (
    order_id INT PRIMARY KEY AUTO_INCREMENT,
    room_id INT NOT NULL,
    customer_id INT NOT NULL,
    check_in_date DATE NOT NULL,
    check_out_date DATE NOT NULL,
    total_amount DECIMAL(10,2) NOT NULL,
    order_status ENUM('待支付','已确认','已完成','已取消') DEFAULT '待支付',
    created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (room_id) REFERENCES room(room_id),
    FOREIGN KEY (customer_id) REFERENCES customer(customer_id)
);

日期字段采用DATE类型确保格式统一,TIMESTAMP自动记录创建时间,状态枚举值完整覆盖订单生命周期。

核心功能实现剖析

  1. 智能客房查询与预订 系统通过动态SQL实现多条件客房检索:
public List<Room> searchAvailableRooms(Date checkIn, Date checkOut, Integer typeId) {
    String sql = "SELECT * FROM room WHERE room_status='空闲' AND room_id NOT IN (" +
                 "SELECT room_id FROM orders WHERE (? < check_out_date AND ? > check_in_date))";
    // 动态添加房型筛选
    if(typeId != null) sql += " AND room_type_id=?";
    // 执行查询并返回结果集
}

该功能通过日期冲突检测算法确保客房预订的准确性,避免重复预订。

客房查询界面

  1. 订单状态机管理 订单处理模块实现了完整的状态流转逻辑:
public boolean updateOrderStatus(Integer orderId, String newStatus) {
    Connection conn = null;
    try {
        conn = DatabaseUtil.getConnection();
        conn.setAutoCommit(false);
        
        // 检查状态流转合法性
        if(!isValidTransition(getCurrentStatus(orderId), newStatus)) {
            throw new IllegalStateException("无效的状态变更");
        }
        
        // 更新订单状态
        String sql = "UPDATE orders SET order_status=? WHERE order_id=?";
        PreparedStatement pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, newStatus);
        pstmt.setInt(2, orderId);
        
        // 如果状态变为"已入住",同步更新房态
        if("已确认".equals(newStatus)) {
            updateRoomStatus(getRoomIdByOrder(orderId), "已入住");
        }
        
        conn.commit();
        return true;
    } catch (SQLException e) {
        rollbackTransaction(conn);
        return false;
    }
}

订单管理界面

  1. 权限控制系统 基于角色的访问控制实现精细化的权限管理:
<filter>
    <filter-name>AuthFilter</filter-name>
    <filter-class>com.hotel.filter.AuthorizationFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AuthFilter</filter-name>
    <url-pattern>/admin/*</url-pattern>
</filter-mapping>
public class AuthorizationFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                       FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpSession session = req.getSession(false);
        
        if(session == null || session.getAttribute("userRole") == null) {
            ((HttpServletResponse) response).sendRedirect("/login.jsp");
            return;
        }
        
        String userRole = (String) session.getAttribute("userRole");
        String requestURI = req.getRequestURI();
        
        // 检查用户权限是否匹配请求路径
        if(!hasPermission(userRole, requestURI)) {
            ((HttpServletResponse) response).sendError(403);
            return;
        }
        
        chain.doFilter(request, response);
    }
}

员工管理界面

  1. 动态房价管理 支持基于季节、房型的差异化定价策略:
public class PriceManager {
    public BigDecimal calculateDynamicPrice(Integer roomId, Date checkIn, Date checkOut) {
        Room room = roomDAO.findById(roomId);
        BigDecimal basePrice = room.getPrice();
        
        // 计算入住天数
        long days = ChronoUnit.DAYS.between(
            checkIn.toInstant(), checkIn.toInstant());
        
        // 获取季节系数
        double seasonFactor = getSeasonFactor(checkIn);
        
        // 计算总价
        return basePrice.multiply(BigDecimal.valueOf(days))
                       .multiply(BigDecimal.valueOf(seasonFactor));
    }
}

房价更新界面

实体模型设计

系统核心实体关系模型采用面向对象设计:

@Entity
public class Room {
    private Integer roomId;
    private String roomNumber;
    private RoomType roomType;
    private RoomStatus status;
    private BigDecimal price;
    private List<Order> orders;
    
    // 业务方法
    public boolean isAvailable(Date checkIn, Date checkOut) {
        return orders.stream().noneMatch(order -> 
            order.hasDateConflict(checkIn, checkOut));
    }
}

@Entity
public class Order {
    private Integer orderId;
    private Room room;
    private Customer customer;
    private Date checkInDate;
    private Date checkOutDate;
    private OrderStatus status;
    
    public boolean hasDateConflict(Date newCheckIn, Date newCheckOut) {
        return newCheckIn.before(checkOutDate) && newCheckOut.after(checkInDate);
    }
}

事务处理与数据一致性

复杂业务操作采用数据库事务保证数据一致性:

@WebServlet("/booking")
public class BookingServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) {
        Connection conn = null;
        try {
            conn = DataSourceUtil.getConnection();
            conn.setAutoCommit(false);
            
            // 1. 检查客房可用性
            Room room = roomDAO.findAvailableRoom(roomId, checkIn, checkOut);
            if(room == null) throw new RoomNotAvailableException();
            
            // 2. 创建订单记录
            Order order = new Order(room, customer, checkIn, checkOut);
            orderDAO.create(order);
            
            // 3. 更新房态
            roomDAO.updateStatus(roomId, RoomStatus.RESERVED);
            
            // 4. 记录审计日志
            auditLogDAO.logBookingAction(customer.getId(), roomId);
            
            conn.commit();
            sendConfirmationEmail(customer, order);
            
        } catch (Exception e) {
            if(conn != null) {
                try { conn.rollback(); } catch (SQLException ex) {}
            }
            handleBookingError(response, e);
        }
    }
}

客房预订界面

性能优化策略

  1. 数据库连接池配置
<Resource name="jdbc/hotelDB"
          auth="Container"
          type="javax.sql.DataSource"
          maxTotal="100"
          maxIdle="30"
          maxWaitMillis="10000"
          driverClassName="com.mysql.cj.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/hotel_db?useSSL=false"/>
  1. 查询结果分页处理
public class PaginationUtil {
    public static <T> PageResult<T> paginateQuery(String baseSql, 
                                                 Object[] params, 
                                                 int page, 
                                                 int size) {
        String countSql = "SELECT COUNT(*) FROM (" + baseSql + ") as total";
        int total = queryForInt(countSql, params);
        
        String pageSql = baseSql + " LIMIT ? OFFSET ?";
        Object[] pageParams = Arrays.copyOf(params, params.length + 2);
        pageParams[params.length] = size;
        pageParams[params.length + 1] = (page - 1) * size;
        
        List<T> data = queryForList(pageSql, pageParams);
        return new PageResult<>(data, total, page, size);
    }
}

系统安全机制

  1. SQL注入防护
public class SafeQueryExecutor {
    public static PreparedStatement prepareStatement(Connection conn, 
                                                    String sql, 
                                                    Object... params) 
                                                    throws SQLException {
        PreparedStatement stmt = conn.prepareStatement(sql);
        for(int i = 0; i < params.length; i++) {
            stmt.setObject(i + 1, params[i]);
        }
        return stmt;
    }
}
  1. 密码安全存储
public class PasswordUtil {
    public static String hashPassword(String plainText) {
        return BCrypt.hashpw(plainText, BCrypt.gensalt(12));
    }
    
    public static boolean verifyPassword(String plainText, String hashed) {
        return BCrypt.checkpw(plainText, hashed);
    }
}

未来优化方向

  1. 微服务架构重构 将单体应用拆分为客房服务、订单服务、用户服务等独立微服务,通过Spring Cloud实现服务治理。客房服务独立部署后可实现更高的并发处理能力。

  2. Redis缓存集成 对热点数据如房型信息、房价策略实施缓存优化:

@Service
public class RoomCacheService {
    @Autowired
    private RedisTemplate<String, Room> redisTemplate;
    
    public Room getRoomWithCache(Integer roomId) {
        String cacheKey = "room:" + roomId;
        Room room = redisTemplate.opsForValue().get(cacheKey);
        if(room == null) {
            room = roomDAO.findById(roomId);
            redisTemplate.opsForValue().set(cacheKey, room, Duration.ofHours(1));
        }
        return room;
    }
}
  1. ** Elasticsearch搜索优化** 实现全文检索和高级筛选功能:
@Repository
public class RoomSearchRepository {
    public List<Room> complexSearch(RoomSearchCriteria criteria) {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        
        if(StringUtils.hasText(criteria.getKeyword())) {
            queryBuilder.withQuery(QueryBuilders.multiMatchQuery(criteria.getKeyword(), 
                "roomNumber", "description", "amenities"));
        }
        
        // 添加范围过滤
        if(criteria.getMinPrice() != null) {
            queryBuilder.withFilter(QueryBuilders.rangeQuery("price").gte(criteria.getMinPrice()));
        }
        
        return elasticsearchTemplate.queryForList(queryBuilder.build(), Room.class);
    }
}
  1. WebSocket实时通知 实现订单状态变更的实时推送:
@ServerEndpoint("/notifications")
public class NotificationEndpoint {
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        session.getUserProperties().put("userId", userId);
    }
    
    @OnMessage
    public void onMessage(String message, Session session) {
        // 处理客户端消息
    }
    
    public static void sendOrderUpdate(Integer userId, Order order) {
        sessions.stream()
            .filter(s -> userId.equals(s.getUserProperties().get("userId")))
            .forEach(s -> s.getAsyncRemote().sendText(
                JSON.toJSONString(new OrderUpdateEvent(order))));
    }
}
  1. Docker容器化部署 通过容器化实现环境标准化和快速部署:
FROM openjdk:8-jre-alpine
COPY target/hotel-system.war /usr/local/tomcat/webapps/
COPY config/application.properties /app/config/
EXPOSE 8080
CMD ["catalina.sh", "run"]

这套酒店智慧管理平台通过严谨的架构设计和深入的技术实现,为酒店行业提供了可靠的数字化解决方案。系统在保持技术稳定性的同时,为后续的功能扩展和技术演进预留了充分的空间。

本文关键词
JSPServlet酒店客房预订管理系统源码解析数据库设计

上下篇

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