基于SSM框架的火车票务在线销售系统 - 源码深度解析

JavaJavaScriptMavenHTMLCSSSSM框架MySQL
2026-02-253 浏览

文章摘要

本项目是一款基于SSM(Spring + Spring MVC + MyBatis)框架构建的火车票务在线销售系统,旨在为乘客和票务管理人员提供一个高效、稳定、易用的数字化票务服务平台。其核心业务价值在于彻底改变了传统线下窗口购票模式,解决了乘客购票流程繁琐、排队耗时、信息不透明以及票务管理效率低下...

随着数字化出行需求的不断增长,传统铁路售票模式面临着效率瓶颈和用户体验挑战。本系统采用SSM(Spring+Spring MVC+MyBatis)技术栈构建了一个全功能的铁路票务数字化平台,实现了从车次查询到订单支付的完整业务流程。

系统架构与技术栈设计

系统采用经典的三层架构模式,表现层基于Spring MVC框架处理Web请求和视图解析。通过精心设计的控制器层,系统能够高效处理用户请求并调用相应的业务逻辑。业务逻辑层由Spring框架的IoC容器统一管理各类Service组件,利用声明式事务管理确保票务交易过程中的数据一致性。数据持久层依托MyBatis框架,通过XML映射文件配置灵活的SQL语句,实现高效的数据访问操作。

在技术选型方面,前端采用HTML+CSS+JavaScript技术组合,结合响应式设计确保在不同设备上的良好显示效果。后端使用Maven进行项目构建和依赖管理,数据库采用MySQL 5.7版本,确保了系统的稳定性和性能。

数据库架构设计深度解析

车次信息表设计

CREATE TABLE train_schedule (
    train_id VARCHAR(20) PRIMARY KEY,
    train_number VARCHAR(10) NOT NULL,
    departure_station VARCHAR(50) NOT NULL,
    arrival_station VARCHAR(50) NOT NULL,
    departure_time DATETIME NOT NULL,
    arrival_time DATETIME NOT NULL,
    duration TIME NOT NULL,
    total_seats INT NOT NULL DEFAULT 0,
    available_seats INT NOT NULL DEFAULT 0,
    price DECIMAL(10,2) NOT NULL,
    status ENUM('active', 'inactive') DEFAULT 'active',
    created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

车次信息表的设计体现了铁路业务的核心逻辑。train_id作为主键采用复合业务标识,既保证了唯一性又具备业务含义。departure_time和arrival_time字段精确到分钟级别,满足铁路运输的时效性要求。available_seats字段实时反映余票情况,通过事务控制确保在高并发场景下的数据一致性。

订单表业务逻辑设计

CREATE TABLE ticket_order (
    order_id VARCHAR(32) PRIMARY KEY,
    user_id INT NOT NULL,
    train_id VARCHAR(20) NOT NULL,
    passenger_name VARCHAR(50) NOT NULL,
    id_card VARCHAR(18) NOT NULL,
    seat_number VARCHAR(10) NOT NULL,
    carriage_number INT NOT NULL,
    order_amount DECIMAL(10,2) NOT NULL,
    order_status ENUM('pending', 'paid', 'cancelled', 'completed') DEFAULT 'pending',
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    pay_time TIMESTAMP NULL,
    version INT DEFAULT 0,
    INDEX idx_user_id (user_id),
    INDEX idx_train_id (train_id),
    FOREIGN KEY (train_id) REFERENCES train_schedule(train_id)
);

订单表设计充分考虑了业务扩展性和数据完整性。order_id采用32位UUID生成,避免订单号猜测风险。version字段实现乐观锁机制,防止超卖现象。订单状态机设计涵盖了待支付、已支付、已取消、已完成四种状态,完整反映了票务生命周期。

核心业务功能实现

车次查询与余票展示

系统通过高效的查询算法实现实时余票计算,前端界面直观展示车次信息和座位余量。

@Service
public class TrainQueryServiceImpl implements TrainQueryService {
    
    @Autowired
    private TrainScheduleMapper trainScheduleMapper;
    
    @Autowired
    private SeatInventoryMapper seatInventoryMapper;
    
    @Override
    public List<TrainScheduleDTO> queryTrains(TrainQueryCondition condition) {
        // 构建查询条件
        Example example = new Example(TrainSchedule.class);
        Example.Criteria criteria = example.createCriteria();
        
        if (StringUtils.isNotBlank(condition.getDepartureStation())) {
            criteria.andEqualTo("departureStation", condition.getDepartureStation());
        }
        if (StringUtils.isNotBlank(condition.getArrivalStation())) {
            criteria.andEqualTo("arrivalStation", condition.getArrivalStation());
        }
        if (condition.getDepartureDate() != null) {
            criteria.andGreaterThanOrEqualTo("departureTime", 
                DateUtil.beginOfDay(condition.getDepartureDate()));
            criteria.andLessThan("departureTime", 
                DateUtil.endOfDay(condition.getDepartureDate()));
        }
        
        // 执行查询并计算余票
        List<TrainSchedule> trains = trainScheduleMapper.selectByExample(example);
        return trains.stream().map(this::convertToDTO).collect(Collectors.toList());
    }
    
    private TrainScheduleDTO convertToDTO(TrainSchedule train) {
        TrainScheduleDTO dto = new TrainScheduleDTO();
        BeanUtils.copyProperties(train, dto);
        
        // 实时计算余票
        int availableSeats = seatInventoryMapper.countAvailableSeats(train.getTrainId());
        dto.setAvailableSeats(availableSeats);
        
        return dto;
    }
}

车次查询界面

座位选择与库存锁定

系统实现智能座位推荐算法,支持用户根据偏好选择座位,并通过分布式锁机制确保库存一致性。

@Controller
@RequestMapping("/seat")
public class SeatSelectionController {
    
    @Autowired
    private SeatSelectionService seatSelectionService;
    
    @PostMapping("/select")
    @ResponseBody
    public ApiResult selectSeats(@RequestBody SeatSelectionRequest request) {
        try {
            // 获取分布式锁
            String lockKey = "seat_lock:" + request.getTrainId() + ":" + request.getCarriageNumber();
            boolean lockAcquired = redisTemplate.opsForValue()
                .setIfAbsent(lockKey, "locked", Duration.ofSeconds(30));
            
            if (!lockAcquired) {
                return ApiResult.error("系统繁忙,请稍后重试");
            }
            
            try {
                SeatSelectionResult result = seatSelectionService.selectSeats(request);
                return ApiResult.success(result);
            } finally {
                // 释放锁
                redisTemplate.delete(lockKey);
            }
        } catch (Exception e) {
            log.error("座位选择异常", e);
            return ApiResult.error("选择失败,请重试");
        }
    }
}

订单生成与支付流程

系统采用事务性订单生成机制,确保订单数据与库存状态的一致性。

@Service
@Transactional
public class OrderServiceImpl implements OrderService {
    
    @Autowired
    private OrderMapper orderMapper;
    
    @Autowired
    private SeatInventoryMapper seatInventoryMapper;
    
    @Override
    public Order createOrder(OrderCreateRequest request) {
        // 验证座位可用性
        SeatInventory seat = seatInventoryMapper.selectBySeatInfo(
            request.getTrainId(), request.getCarriageNumber(), request.getSeatNumber());
        
        if (seat == null || !seat.isAvailable()) {
            throw new BusinessException("所选座位不可用");
        }
        
        // 生成订单号
        String orderId = OrderIdGenerator.generate();
        
        // 创建订单
        Order order = new Order();
        order.setOrderId(orderId);
        order.setUserId(request.getUserId());
        order.setTrainId(request.getTrainId());
        order.setPassengerName(request.getPassengerName());
        order.setIdCard(request.getIdCard());
        order.setSeatNumber(request.getSeatNumber());
        order.setCarriageNumber(request.getCarriageNumber());
        order.setOrderAmount(calculateOrderAmount(request));
        order.setOrderStatus(OrderStatus.PENDING);
        
        orderMapper.insert(order);
        
        // 锁定座位库存
        seat.setStatus(SeatStatus.LOCKED);
        seat.setLockedTime(new Date());
        seatInventoryMapper.updateByPrimaryKey(seat);
        
        return order;
    }
}

订单确认页面

支付处理与状态更新

系统集成多种支付方式,通过异步通知机制确保支付状态及时同步。

@Service
public class PaymentServiceImpl implements PaymentService {
    
    @Autowired
    private OrderMapper orderMapper;
    
    @Autowired
    private SeatInventoryMapper seatInventoryMapper;
    
    @Async
    @Transactional
    @Override
    public void processPaymentCallback(PaymentCallbackRequest request) {
        Order order = orderMapper.selectByOrderId(request.getOrderId());
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        if (request.isSuccess()) {
            // 支付成功,更新订单状态
            order.setOrderStatus(OrderStatus.PAID);
            order.setPayTime(new Date());
            orderMapper.updateByPrimaryKey(order);
            
            // 确认座位占用
            SeatInventory seat = seatInventoryMapper.selectBySeatInfo(
                order.getTrainId(), order.getCarriageNumber(), order.getSeatNumber());
            seat.setStatus(SeatStatus.OCCUPIED);
            seatInventoryMapper.updateByPrimaryKey(seat);
            
            // 发送出票通知
            sendTicketIssuedNotification(order);
        } else {
            // 支付失败,释放座位
            order.setOrderStatus(OrderStatus.CANCELLED);
            orderMapper.updateByPrimaryKey(order);
            
            SeatInventory seat = seatInventoryMapper.selectBySeatInfo(
                order.getTrainId(), order.getCarriageNumber(), order.getSeatNumber());
            seat.setStatus(SeatStatus.AVAILABLE);
            seat.setLockedTime(null);
            seatInventoryMapper.updateByPrimaryKey(seat);
        }
    }
}

实体模型与业务逻辑封装

系统通过精细的实体模型设计,将复杂的铁路票务业务抽象为可管理的对象关系。核心实体包括用户、车次、车厢、座位、订单等,各实体之间通过明确的关系映射实现业务逻辑的连贯性。

@Entity
@Table(name = "train_schedule")
public class TrainSchedule {
    @Id
    private String trainId;
    
    private String trainNumber;
    private String departureStation;
    private String arrivalStation;
    
    @Temporal(TemporalType.TIMESTAMP)
    private Date departureTime;
    
    @Temporal(TemporalType.TIMESTAMP)
    private Date arrivalTime;
    
    private Integer totalSeats;
    private Integer availableSeats;
    private BigDecimal price;
    private String status;
    
    // 关联车厢信息
    @OneToMany(mappedBy = "trainSchedule")
    private List<Carriage> carriages;
    
    // 关联订单信息
    @OneToMany(mappedBy = "trainSchedule")
    private List<Order> orders;
}

后台管理系统

性能优化与安全设计

系统在性能方面进行了多重优化。数据库层面通过合理的索引设计和查询优化,确保在大数据量下的快速响应。应用层面采用多级缓存策略,对热点车次信息和座位状态进行缓存,显著降低数据库压力。

安全设计方面,系统实现了完整的身份认证和授权机制,对敏感操作进行日志记录和审计。支付环节采用加密传输和签名验证,确保交易数据的安全性。

@Configuration
@EnableCaching
public class CacheConfig {
    
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(30))
            .disableCachingNullValues()
            .serializeKeysWith(RedisSerializationContext.SerializationPair
                .fromSerializer(new StringRedisSerializer()))
            .serializeValuesWith(RedisSerializationContext.SerializationPair
                .fromSerializer(new GenericJackson2JsonRedisSerializer()));
        
        return RedisCacheManager.builder(factory)
            .cacheDefaults(config)
            .transactionAware()
            .build();
    }
}

系统扩展与未来优化方向

智能推荐算法升级

引入机器学习算法分析用户购票行为,提供个性化的车次推荐和座位建议。通过历史数据训练预测模型,预估热门线路的票务需求,优化库存分配策略。

微服务架构迁移

将单体应用拆分为用户服务、票务服务、订单服务、支付服务等独立微服务,提升系统的可扩展性和维护性。采用Spring Cloud技术栈实现服务治理和分布式事务管理。

移动端体验优化

开发原生移动应用,利用设备特性实现更便捷的购票体验。集成生物识别支付、离线车票展示等功能,提升移动场景下的用户体验。

大数据分析平台

构建票务数据仓库,通过ETL流程整合业务数据,建立多维数据分析模型。为运营决策提供数据支持,实现精准的票价策略和运力调配。

高可用架构升级

引入分布式数据库和消息队列,实现系统的高可用和容灾能力。通过负载均衡和自动扩缩容机制,应对节假日等高峰期的访问压力。

数据统计界面

该系统通过严谨的架构设计和精细的业务实现,为铁路票务数字化提供了完整的技术解决方案。其模块化设计和扩展性架构为后续的功能演进和技术升级奠定了坚实基础,具备良好的商业应用价值和技术示范意义。

本文关键词
SSM框架火车票务系统源码解析数据库设计订单管理

上下篇

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