主题切换
TTMS剧院管理项目整体架构,课设(非求职项目)
本项目采用经典 MVC 三层架构进行开发,实现请求控制、业务逻辑、数据访问的分层解耦,结构清晰、职责明确、易于维护。
- Controller 层(控制层):统一接收前端请求,完成参数校验、权限判断与请求分发,是前后端交互的统一入口。
- Service 层(业务逻辑层):封装核心业务流程,处理选座、锁票、下单、支付、评论、权限校验等逻辑,是整个系统的核心。
- DAO 层(数据访问层):专注数据库交互,通过原生 JDBC 实现数据的增删改查,完成数据持久化。
前后端交互
项目采用 Ajax 异步通信 实现前后端分离交互:
- 前端通过 Ajax 发送请求,页面无刷新获取数据;
- 后端统一返回 JSON 格式数据,前端直接解析渲染,提升体验与交互流畅度。
前端技术栈
前端使用 HTML + CSS + JavaScript 静态页面技术栈开发:
- HTML + CSS 负责页面结构与样式;
- JavaScript 负责页面交互、表单验证与 Ajax 请求;
- 分为用户端与管理员端两套页面,满足不同角色业务需求。
统一配置
- 项目基于 Maven 构建,统一管理依赖和版本,方便团队协作和打包部署。
2. 技术亮点介绍
① 数据库设计与 DAO 工厂模式解耦
亮点:使用 DAO 工厂模式 + 接口化设计,实现数据访问层与业务层解耦。
我们通过定义 DAO 接口(如 iCustomerOrderDAO),并使用 DAOFactory 工厂类统一获取 DAO 实例。 这种方式让业务层不依赖具体实现,未来更换数据库或切换实现类时,业务代码完全不用修改,系统耦合度低、扩展性强。
(为什么要这么做:DAO 工厂模式 = 统一创建 DAO,解耦业务层与数据层,便于扩展和维护。 对比spring工厂)
java
// DAO 工厂获取实例
public static synchronized iCustomerOrderDAO createCustomerOrderDAO() {
if (customerOrderDao == null)
customerOrderDao = new CustomerOrderDAO();
return customerOrderDao;
}
// Service 层面向接口编程
private iCustomerOrderDAO customerOrderDAO = DAOFactory.createCustomerOrderDAO();② 核心业务:事务控制 + 并发安全(选座 / 锁票 / 订单)
亮点:基于状态机 + 事务 + 原子更新,彻底解决高并发下“超卖”问题。
选座购票是系统核心,为避免多用户同时抢票导致数据错乱,我们采用:
- 数据库事务保证锁票、生成订单原子性;
- 悲观锁锁定排片资源;
- 票状态机机制控制票务流转;
- SQL 原子更新保证并发安全。
票状态流转:
0 → 可售
1 → 已锁定(待支付)
2 → 已售出(已支付)
3 → 已退票
4 → 已检票锁票核心 SQL(原子更新 + 状态校验):
sql
UPDATE ticket
SET ticket_status=1, ticket_locktime=NOW()
WHERE ticket_id=? AND sched_id=? AND ticket_status=0通过状态判断 + 数据库原子性,保证同一时间只有一个请求能锁票成功,天然防超卖、防重复锁定。
事务流程:
java
conn.setAutoCommit(false);
try {
// 锁定排片
lockScheduleForUpdate(conn, scheduleId);
// 批量锁票
for (long ticketId : ticketIds) {
updateTicketStatus(conn, ticketId, 1);
}
// 创建订单
insertSale();
insertSaleItem();
conn.commit();
} catch (Exception e) {
conn.rollback();
}③ 统一前后端交互:过滤器 + JSON 标准化响应
亮点:使用 Filter 统一处理全局逻辑,JSON 规范前后端交互。
我们使用 Filter 过滤器实现:
- 全局编码统一处理;
- 登录状态校验;
- 未登录用户禁止访问后台;
后端接口统一返回 org.json.JSONObject 格式数据,结构规范、前端易于解析,让前后端交互更标准、更稳定。
④ 灵活可扩展的数据字典设计
亮点:通用树形数据字典,统一管理系统所有类型与状态。
我们设计了 data_dict 通用配置表,采用父子层级树形结构,集中管理影片类型、票状态、订单状态、影厅类型等所有枚举数据,无需为每类配置单独建表。
dict_id | super_dict_id | dict_name | dict_value
--------|---------------|------------|-----------
1 | NULL | 数据字典 | 根节点
2 | 1 | PLAYTYPE | 影片类型
5 | 2 | History | 历史
6 | 2 | Anime | 动漫优势:
- 统一管理、结构清晰
- 无限层级扩展
- 无需修改代码,直接在数据库配置
- 前端下拉框可直接读取,高度灵活
3. 高频问答环节
① 为什么不用 Spring、SpringBoot 等框架?
这是一个教学型项目,目的是夯实底层基础:
- 理解 Servlet
- 掌握 JDBC 原生操作与事务原理
- 理解 MVC、DAO、工厂模式思想
- 为后续学习框架打下扎实原理基础
② 如果做性能优化,你会怎么做?
- 引入 数据库连接池(Druid/HikariCP)提升连接复用;
- 使用 Redis 缓存热门排片、座位图、首页数据;
- 静态资源(JS/CSS/图片)使用 CDN 加速;
- 优化分页查询、添加索引、避免全表扫描;
- 异步化处理非核心流程。
③ 如何保证系统数据安全?
- 使用 PreparedStatement 预编译,防止 SQL 注入;
- 密码采用 bcrypt 加密存储,不可逆、自动加盐;
- 通过 Session 校验 防止越权与篡改;
- 生产环境可启用 HTTPS 保证传输加密;
- 关键接口添加 幂等性 防止重复提交。