基于SSM框架的航班机票销售预订平台 - 源码深度解析

JavaJavaScriptMavenHTMLCSSSSM框架MySQLJSP+Servlet
2026-03-053 浏览

文章摘要

本项目是基于SSM(Spring+SpringMVC+MyBatis)框架开发的航班机票销售预订平台,旨在为旅客和航空公司提供高效、可靠的在线票务服务。系统核心业务价值在于解决了传统购票流程中信息不透明、操作繁琐、数据一致性难保障等痛点,通过集中化的航班信息管理和实时库存更新,显著提升了机票销售效率...

在现代航空旅行日益普及的背景下,高效的票务管理系统成为连接旅客与航空公司的关键枢纽。传统线下购票模式存在信息更新滞后、操作流程繁琐、数据一致性难以保障等固有痛点,尤其在高并发预订场景下容易引发超售风险。针对这些行业挑战,基于SSM(Spring+SpringMVC+MyBatis)框架构建的航班机票销售预订平台应运而生,通过模块化架构设计和严谨的事务控制,实现了航班管理、动态定价、在线支付与库存实时更新的全流程数字化管控。

技术架构设计

系统采用经典的三层架构模式,通过依赖注入(DI)和面向切面编程(AOP)实现业务组件的解耦与复用。Spring Framework作为控制反转(IoC)容器,统一管理Service层业务对象与DAO层数据访问实例的依赖关系。例如,通过注解方式声明事务边界,确保机票预订过程中航班库存扣减与订单生成的原子性操作:

@Service
@Transactional
public class FlightOrderServiceImpl implements FlightOrderService {
    @Autowired
    private FlightInventoryMapper flightInventoryMapper;
    
    @Override
    public boolean createOrder(OrderDTO orderDTO) {
        // 1. 校验航班余票
        FlightInventory inventory = flightInventoryMapper.selectForUpdate(orderDTO.getFlightId());
        if (inventory.getRemainingSeats() < orderDTO.getPassengerCount()) {
            throw new BusinessException("剩余座位不足");
        }
        
        // 2. 扣减库存(悲观锁保证数据一致性)
        inventory.setRemainingSeats(inventory.getRemainingSeats() - orderDTO.getPassengerCount());
        flightInventoryMapper.updateInventory(inventory);
        
        // 3. 生成订单记录
        return orderMapper.insertOrder(orderDTO) > 0;
    }
}

表现层采用SpringMVC框架处理HTTP请求路由,通过@Controller注解定义 RESTful 接口,并结合拦截器实现用户身份验证。以下代码展示了航班查询接口的参数绑定与动态响应机制:

@Controller
@RequestMapping("/flight")
public class FlightController {
    @Autowired
    private FlightService flightService;
    
    @RequestMapping(value = "/search", method = RequestMethod.GET)
    @ResponseBody
    public ResultModel searchFlights(
            @RequestParam String departureCity,
            @RequestParam String arrivalCity,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date departureDate) {
        List<FlightVO> flights = flightService.searchByCriteria(departureCity, arrivalCity, departureDate);
        return ResultModel.success(flights);
    }
}

数据持久层依托MyBatis框架,通过XML映射文件将Java对象与数据库表字段动态关联。以下示例展示了动态SQL构建多条件航班查询的灵活实现:

<!-- FlightMapper.xml -->
<select id="selectByDynamicConditions" parameterType="map" resultMap="FlightResultMap">
    SELECT flight_id, flight_number, departure_airport, arrival_airport, 
           departure_time, arrival_time, ticket_price, remaining_seats
    FROM flight_inventory
    <where>
        <if test="departureCity != null and departureCity != ''">
            AND departure_airport LIKE CONCAT('%', #{departureCity}, '%')
        </if>
        <if test="arrivalCity != null and arrivalCity != ''">
            AND arrival_airport LIKE CONCAT('%', #{arrivalCity}, '%')
        </if>
        <if test="departureDate != null">
            AND DATE(departure_time) = DATE(#{departureDate})
        </if>
        <if test="minPrice != null">
            AND ticket_price >= #{minPrice}
        </if>
        <if test="maxPrice != null">
            AND ticket_price <= #{maxPrice}
        </if>
    </where>
    ORDER BY departure_time ASC
</select>

前端页面采用JSP模板引擎渲染,结合jQuery库实现异步数据交互。航班选择页面通过Ajax调用后端接口动态加载筛选结果,并通过DOM操作实时更新座位余量提示:

function loadFlightList() {
    $.ajax({
        url: '/flight/search',
        type: 'GET',
        data: {
            departureCity: $('#departureCity').val(),
            arrivalCity: $('#arrivalCity').val(),
            departureDate: $('#departureDate').val()
        },
        success: function(response) {
            if (response.success) {
                renderFlightTable(response.data);
            } else {
                alert('查询失败:' + response.message);
            }
        }
    });
}

数据库架构精析

系统数据库包含5张核心表,通过外键关联实现数据完整性约束。其中航班库存表(flight_inventory)采用乐观锁机制控制并发修改,用户表(user)通过角色字段区分终端旅客与管理员权限,订单表(flight_order)则记录完整的交易流水。

航班库存表设计 采用业务主键与自然主键结合的方式,既保证查询效率又符合业务逻辑:

CREATE TABLE flight_inventory (
    flight_id VARCHAR(20) PRIMARY KEY COMMENT '航班业务ID',
    flight_number VARCHAR(10) NOT NULL COMMENT '航班号',
    aircraft_model VARCHAR(20) COMMENT '机型',
    departure_airport VARCHAR(50) NOT NULL COMMENT '出发机场',
    arrival_airport VARCHAR(50) NOT NULL COMMENT '到达机场',
    departure_time DATETIME NOT NULL COMMENT '计划起飞时间',
    arrival_time DATETIME NOT NULL COMMENT '计划到达时间',
    total_seats INT DEFAULT 0 COMMENT '总座位数',
    remaining_seats INT DEFAULT 0 COMMENT '剩余座位数',
    ticket_price DECIMAL(10,2) COMMENT '基准票价',
    version INT DEFAULT 0 COMMENT '乐观锁版本号',
    INDEX idx_departure_arrival (departure_airport, arrival_airport),
    INDEX idx_departure_time (departure_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='航班库存表';

该表通过version字段实现乐观锁控制,在并发订票场景下避免超售问题。索引设计覆盖了常见的查询组合(出发地-目的地、起飞时间),显著提升搜索性能。

订单表结构 采用星型 schema 设计,通过冗余存储关键业务字段降低多表关联查询开销:

CREATE TABLE flight_order (
    order_id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '订单ID',
    order_number VARCHAR(32) UNIQUE NOT NULL COMMENT '订单编号',
    user_id BIGINT NOT NULL COMMENT '用户ID',
    flight_id VARCHAR(20) NOT NULL COMMENT '航班ID',
    passenger_name VARCHAR(50) NOT NULL COMMENT '乘机人姓名',
    passenger_idcard VARCHAR(18) NOT NULL COMMENT '乘机人证件号',
    order_amount DECIMAL(10,2) NOT NULL COMMENT '订单金额',
    order_status TINYINT DEFAULT 0 COMMENT '订单状态(0-待支付 1-已支付 2-已取消)',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    pay_time DATETIME COMMENT '支付时间',
    flight_number VARCHAR(10) COMMENT '航班号(冗余存储)',
    departure_time DATETIME COMMENT '起飞时间(冗余存储)',
    FOREIGN KEY (user_id) REFERENCES user(user_id),
    FOREIGN KEY (flight_id) REFERENCES flight_inventory(flight_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='机票订单表';

冗余字段设计虽然增加了存储空间,但避免了订单列表查询时频繁联接航班表的需求,尤其在高并发读取场景下可降低数据库负载。

核心功能实现解析

1. 智能航班搜索与动态筛选

旅客通过出发地、目的地和日期条件查询可售航班,系统后端通过MyBatis动态SQL构建多维度查询语句。前端界面采用渐进式加载策略,在用户输入过程中实时触发搜索建议:

航班查询界面

搜索功能的核心服务层代码通过构建查询条件对象,实现灵活的条件组合:

@Service
public class FlightSearchServiceImpl implements FlightSearchService {
    public List<FlightVO> searchFlights(FlightQueryDTO queryDTO) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("departureCity", queryDTO.getDepartureCity());
        paramMap.put("arrivalCity", queryDTO.getArrivalCity());
        paramMap.put("departureDate", queryDTO.getDepartureDate());
        paramMap.put("minPrice", queryDTO.getPriceRange().getMin());
        paramMap.put("maxPrice", queryDTO.getPriceRange().getMax());
        
        return flightMapper.selectByDynamicConditions(paramMap);
    }
}

2. 机票预订与库存一致性保障

预订流程包含座位可用性校验、价格计算、订单生成等关键步骤。系统通过@Transactional注解声明事务边界,确保库存扣减与订单创建的原子性:

机票预订界面

库存扣减操作采用悲观锁机制,在查询阶段即通过SELECT ... FOR UPDATE锁定记录,防止并发修改:

@Mapper
public interface FlightInventoryMapper {
    @Select("SELECT * FROM flight_inventory WHERE flight_id = #{flightId} FOR UPDATE")
    FlightInventory selectForUpdate(String flightId);
    
    @Update("UPDATE flight_inventory SET remaining_seats = #{remainingSeats}, version = version + 1 WHERE flight_id = #{flightId} AND version = #{version}")
    int updateWithOptimisticLock(FlightInventory inventory);
}

3. 多角色权限管理体系

系统通过用户表(user)中的role字段区分普通用户与管理员权限。SpringMVC拦截器在请求预处理阶段验证会话状态与操作权限:

@Component
public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        UserVO user = (UserVO) session.getAttribute("currentUser");
        
        if (user == null) {
            response.sendRedirect("/login");
            return false;
        }
        
        // 管理员接口权限校验
        if (handler instanceof HandlerMethod) {
            RequireAdmin requireAdmin = ((HandlerMethod) handler).getMethodAnnotation(RequireAdmin.class);
            if (requireAdmin != null && !user.getRole().equals("admin")) {
                throw new PermissionDeniedException("需要管理员权限");
            }
        }
        return true;
    }
}

管理员登录后可通过专属界面管理航班信息、调整票价策略、监控销售数据:

航班管理界面

4. 订单状态机与业务流程闭环

订单生命周期包含"待支付→已支付→已出票→已完成"等状态流转。系统通过状态模式(State Pattern)封装不同状态下的业务规则:

public abstract class OrderState {
    protected FlightOrder order;
    
    public abstract void pay();
    public abstract void cancel();
    public abstract void complete();
}

@Component
public class PendingPaymentState extends OrderState {
    @Override
    public void pay() {
        // 执行支付逻辑
        order.setStatus(OrderStatus.PAID);
        order.setState(new PaidState(order));
        
        // 记录支付时间
        order.setPayTime(new Date());
        orderMapper.updateStatus(order);
    }
    
    @Override
    public void cancel() {
        // 释放库存
        flightInventoryMapper.increaseSeats(order.getFlightId(), order.getPassengerCount());
        
        order.setStatus(OrderStatus.CANCELLED);
        order.setState(new CancelledState(order));
        orderMapper.updateStatus(order);
    }
}

用户可在个人中心查看历史订单并进行状态操作:

订单管理界面

实体模型与业务对象映射

系统通过MyBatis的resultMap配置实现Java对象与数据库表的精细映射,尤其在处理复杂关联关系时展现框架优势:

<resultMap id="OrderDetailResultMap" type="com.airline.model.FlightOrder">
    <id property="orderId" column="order_id"/>
    <result property="orderNumber" column="order_number"/>
    <result property="orderAmount" column="order_amount"/>
    <result property="orderStatus" column="order_status"/>
    
    <!-- 关联用户信息 -->
    <association property="user" javaType="com.airline.model.User">
        <id property="userId" column="user_id"/>
        <result property="username" column="username"/>
        <result property="phone" column="phone"/>
    </association>
    
    <!-- 关联航班信息 -->
    <association property="flight" javaType="com.airline.model.FlightInventory">
        <id property="flightId" column="flight_id"/>
        <result property="flightNumber" column="flight_number"/>
        <result property="departureTime" column="departure_time"/>
        <result property="arrivalTime" column="arrival_time"/>
    </association>
    
    <!-- 集合映射:乘机人列表 -->
    <collection property="passengers" ofType="com.airline.model.Passenger">
        <result property="name" column="passenger_name"/>
        <result property="idCard" column="passenger_idcard"/>
    </collection>
</resultMap>

性能优化与扩展方向

当前系统在应对中小规模并发场景下表现稳定,未来可从以下几个方向进一步提升系统能力:

  1. 缓存策略升级:引入Redis集群实现热点航班数据的分布式缓存,将航班搜索结果的QPS提升3-5倍。可通过Spring Cache抽象层统一管理缓存注解:
@Cacheable(value = "flights", key = "#queryDTO.hashCode()", unless = "#result == null")
public List<FlightVO> searchFlights(FlightQueryDTO queryDTO) {
    return flightMapper.selectByDynamicConditions(queryDTO);
}
  1. 异步任务处理:使用Spring的@Async注解将订单超时取消、出票通知等非实时操作异步化,通过消息队列削峰填谷:
@Async("taskExecutor")
@EventListener
public void handleOrderTimeout(OrderTimeoutEvent event) {
    FlightOrder order = orderMapper.selectById(event.getOrderId());
    if (order.getStatus() == OrderStatus.PENDING_PAYMENT) {
        order.cancel();
    }
}
  1. 分库分表架构:当订单数据量超过千万级时,可按时间维度进行分表存储,通过Sharding-JDBC中间件实现透明路由。

  2. 价格动态引擎:构建基于历史数据和实时需求的智能定价模型,通过独立的价格服务动态调整航班票价,提升收益管理水平。

  3. 多租户支持:通过数据库 schema 隔离或数据行级权限控制,支持第三方票务代理机构接入,扩展平台商业模式。

该系统通过严谨的架构设计和细致的技术实现,为航空票务领域提供了稳定可靠的数字基座。其模块化设计理念与可扩展的技术栈选型,为后续功能迭代与性能优化奠定了坚实基础。

本文关键词
SSM框架航班机票销售预订平台源码解析Spring+SpringMVC+MyBatis

上下篇

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