在数字化浪潮席卷服务业的今天,传统影院运营模式正面临深刻的转型压力。观众排队购票的漫长等待、场次与座位信息的不透明、以及影院方在影片排期和票务统计上的低效,都催生了对智能化管理平台的迫切需求。本系统正是针对这一市场痛点,采用经典的SSH技术栈,构建了一个集前台购票与后台管理于一体的综合性解决方案,旨在打造一个高效、便捷、数据驱动的影院运营中枢。
系统架构严格遵循MVC设计模式,实现了表现层、业务逻辑层与数据持久层的清晰分离。表现层由Struts2框架担当,它通过精心配置的struts.xml文件,将前端的用户请求(如/user_login.action)准确地路由到对应的后端Action类进行处理。Struts2强大的拦截器机制被用于实现统一的用户身份验证与请求参数校验,确保了系统的安全性与数据的规范性。业务逻辑层由Spring框架的IoC容器统一管理,其核心优势在于依赖注入,它彻底解耦了诸如MovieService、OrderService等业务组件。例如,在处理购票业务时,OrderAction并不需要直接实例化OrderServiceImpl,而是通过Spring的配置由容器自动注入,这不仅降低了代码的耦合度,也使得单元测试变得更加容易。同时,Spring的声明式事务管理被应用于购票、支付等核心业务方法上,通过@Transactional注解,确保了这些多步骤操作的数据一致性。数据持久层则由Hibernate框架负责,它通过对象关系映射将Java实体对象与数据库中的表关联起来。系统配置了由Spring托管的SessionFactory,Hibernate的Session生命周期由Spring管理,简化了数据库连接的获取与释放,提升了开发效率和系统性能。
数据库设计是系统稳定性的基石。本系统共设计了7张核心数据表,其结构体现了业务逻辑的严谨性。以t_order订单表为例,其设计不仅完整记录了交易信息,还通过外键约束确保了数据的参照完整性。
CREATE TABLE `t_order` (
`orderId` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单ID',
`userId` int(11) DEFAULT NULL COMMENT '用户ID',
`scheduleId` int(11) DEFAULT NULL COMMENT '场次ID',
`orderPosition` varchar(255) DEFAULT NULL COMMENT '座位信息',
`orderPrice` double DEFAULT NULL COMMENT '订单价格',
`orderPayType` int(11) DEFAULT NULL COMMENT '支付方式',
`orderPhone` varchar(255) DEFAULT NULL COMMENT '联系电话',
`orderDate` varchar(255) DEFAULT NULL COMMENT '下单时间',
`orderStatus` int(11) DEFAULT NULL COMMENT '订单状态',
PRIMARY KEY (`orderId`),
KEY `FK_order_userId` (`userId`),
KEY `FK_order_scheduleId` (`scheduleId`),
CONSTRAINT `FK_order_scheduleId` FOREIGN KEY (`scheduleId`) REFERENCES `t_schedule` (`scheduleId`),
CONSTRAINT `FK_order_userId` FOREIGN KEY (`userId`) REFERENCES `t_user` (`userId`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
该表通过userId和scheduleId分别关联用户表和场次表,清晰地记录了“谁”在“何时”购买了“哪场电影”的票。orderPosition字段以字符串形式存储座位号(如"5排6座"),orderStatus字段则用于标识订单的生命周期(如待支付、已支付、已取消等),是业务流程流转的关键。另一个核心表t_schedule(场次表)的设计同样值得关注,它作为连接电影t_movie和影厅t_hall的枢纽,记录了放映时间、票价等动态信息,是库存管理的基础。
CREATE TABLE `t_schedule` (
`scheduleId` int(11) NOT NULL AUTO_INCREMENT COMMENT '场次ID',
`movieId` int(11) DEFAULT NULL COMMENT '电影ID',
`hallId` int(11) DEFAULT NULL COMMENT '影厅ID',
`schedulePrice` double DEFAULT NULL COMMENT '场次价格',
`scheduleRemain` int(11) DEFAULT NULL COMMENT '剩余票数',
`scheduleStartTime` varchar(255) DEFAULT NULL COMMENT '放映时间',
PRIMARY KEY (`scheduleId`),
KEY `FK_schedule_hallId` (`hallId`),
KEY `FK_schedule_movieId` (`movieId`),
CONSTRAINT `FK_schedule_hallId` FOREIGN KEY (`hallId`) REFERENCES `t_hall` (`hallId`),
CONSTRAINT `FK_schedule_movieId` FOREIGN KEY (`movieId`) REFERENCES `t_movie` (`movieId`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;
在核心功能实现上,在线选座与购票流程最具代表性。前端页面通过AJAX技术动态拉取指定场次的座位图,并利用CSS和JavaScript渲染出可视化的选座界面。已售座位会被标记为不可选状态,为用户提供直观的导引。

当用户选择座位并提交订单时,请求会被Struts2的拦截器捕获并转发至OrderAction。该Action通过Spring注入的OrderService来执行业务逻辑。以下是OrderAction中处理创建订单请求的核心代码片段,展示了如何从前端接收参数并调用服务层方法。
// OrderAction.java 中处理创建订单的方法
public String createOrder() {
// 从Session中获取当前登录用户
User currentUser = (User) ActionContext.getContext().getSession().get("currentUser");
if (currentUser == null) {
addActionError("请先登录!");
return "login"; // 跳转至登录页
}
try {
// 设置订单所属用户
order.setUser(currentUser);
// 调用业务层的创建订单方法
orderService.createOrder(order);
addActionMessage("订单创建成功,请尽快支付!");
return SUCCESS;
} catch (Exception e) {
e.printStackTrace();
addActionError("订单创建失败:" + e.getMessage());
return ERROR;
}
}
而OrderServiceImpl则包含了具体的业务逻辑,它需要处理库存检查、订单生成、座位锁定等事务性操作。@Transactional注解确保了这些操作在一个数据库事务中完成,避免出现数据不一致的情况。
// OrderServiceImpl.java 中的核心业务方法
@Service("orderService")
@Transactional // 声明式事务管理
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderDao orderDao;
@Autowired
private ScheduleDao scheduleDao;
@Override
public void createOrder(Order order) throws Exception {
// 1. 检查场次余票
Schedule schedule = scheduleDao.get(Schedule.class, order.getSchedule().getScheduleId());
int ticketsToBuy = order.getOrderPosition().split(",").length; // 计算购买张数(根据所选座位数)
if (schedule.getScheduleRemain() < ticketsToBuy) {
throw new RuntimeException("余票不足!");
}
// 2. 生成订单号、设置订单状态等...
order.setOrderNo(generateOrderNo());
order.setOrderStatus(OrderStatus.UNPAID);
// 3. 保存订单
orderDao.save(order);
// 4. 更新场次余票
schedule.setScheduleRemain(schedule.getScheduleRemain() - ticketsToBuy);
scheduleDao.update(schedule);
}
}
影片信息管理是后台管理的核心。管理员可以通过后台系统便捷地添加新影片、上传海报、编辑简介和设置影片类型。下图展示了后台影片管理的界面,管理员可以对影片进行增删改查等一系列操作。

对应的MovieAction负责处理前端的各类请求,并通过调用MovieService来完成业务操作。其代码结构清晰,体现了Struts2与Spring的良好集成。
// MovieAction.java 中处理影片列表查询的方法
public class MovieAction extends ActionSupport {
private List<Movie> movieList;
@Autowired
private MovieService movieService;
public String list() {
// 调用服务层获取所有影片列表
movieList = movieService.findAllMovies();
return SUCCESS;
}
// Getter and Setter...
}
数据持久化由Hibernate实现的DAO层完成。以MovieDaoImpl为例,它继承了Spring提供的HibernateDaoSupport类,可以方便地使用HibernateTemplate进行数据库操作。
// MovieDaoImpl.java 使用Hibernate进行数据访问
@Repository("movieDao")
public class MovieDaoImpl extends HibernateDaoSupport implements MovieDao {
@Autowired
public void setSuperSessionFactory(SessionFactory sessionFactory) {
super.setSessionFactory(sessionFactory);
}
@Override
public List<Movie> findAll() {
String hql = "FROM Movie m ORDER BY m.movieReleaseDate DESC";
return (List<Movie>) this.getHibernateTemplate().find(hql);
}
@Override
public void save(Movie movie) {
this.getHibernateTemplate().save(movie);
}
}
系统的实体模型设计准确地反映了业务领域。例如,Order订单实体与User用户实体、Schedule场次实体之间是多对一的关系,这种关系在Hibernate的映射文件或注解中得到了明确定义,使得在Java代码中可以以面向对象的方式轻松导航,例如通过order.getUser().getUserName()获取订单所属用户的姓名。

留言板功能增强了用户互动性,用户可以在影片详情页发表评论或提问,管理员则可以在后台进行回复或管理。

尽管当前系统已实现了核心票务功能,但从长远发展和提升竞争力的角度考虑,仍有若干值得优化的方向。首先,引入Redis等内存数据库作为缓存层是提升性能的首选方案。可以将热门的影片信息、近期场次数据缓存起来,显著降低数据库的访问压力。其次,集成第三方支付平台(如支付宝、微信支付)是提升用户体验的关键步骤,这需要在现有支付流程中接入对方的SDK并实现异步通知接口。第三,开发移动端APP或深化微信小程序支持,以适应移动互联网的趋势,这可以通过提供RESTful API供移动端调用来实现。第四,引入推荐算法,根据用户的购票历史和浏览行为,为其推荐可能感兴趣的影片,这可以基于协同过滤或内容过滤算法实现。最后,强化数据统计分析功能,为影院管理者提供更直观的上座率、票房收入、影片热度等多维度数据报表,辅助其经营决策。
该系统是SSH这一经典JavaEE技术组合在实体经济数字化转型中的一次成功实践。它通过清晰的分层架构、严谨的数据库设计和完善的功能模块,证明了成熟技术栈在构建稳定、可维护的企业级应用方面的强大生命力。该系统不仅为影院提供了高效的运营管理工具,也为用户创造了便捷、透明的现代化购票体验,具备了良好的实用价值和推广前景。