火车售票系统
一、系统开发平台
题目:火车售票系统
开发工具:InteiJIDEA
数据库:mysq
操作系统:macOSCataina
开发语言:Java,htm,CSS,JavaScript(Webapp 的开发)
二、数据库规划
2.1 任务陈述
做一个火车票售票系统:对火车的售票进行管理。主要功能:车次管理(车次、起止地点、到达时间、开车时间)、每一车次的坐席管理(车厢号、座位号)、售票(直达、换乘等)、改签(更改时间,更改位置)、退票、查询(余票,订单)、用户管理(注册,登录)。
2.2 任务目标
本系统主要可以实现以下任务目标:
1、系统可以实现对用户的管理——包含用户注册和用户登录。用户注册所需的信息:昵称,身份(学生,非学生),登录密码,真实姓名,身份证号和验证码。用户通过昵称和密码登录。
2、购票模块:用户登录后可以进行购票。购票分为直达购买和换乘购买。系统可以通过起止车站和出行时间准确的获取空的车座,您需要确定的信息——出行时间、车次、起止车站、票种、席别、票价、身份证和真实姓名。
3.查询模块:分为车次查询(查询所有正常运行的火车的经停火车站),余票查询(剩余车座的查询)和暂停运营查询(查询所有暂停运行的火车)
车次查询得到的信息:火车号、经停的火车站、达到时间、在该车站的停止时间和火车已经行驶的路程。
余票查询得到的信息:出行日期、火车号、车座等级和车票剩余。
暂停运营查询得到的信息:停运的火车号和火车类型。
4.订单管理模块:分为退票模块和改签模块。退票——将订单退回。改签可以分为改变位置和改变出行时间。
三、系统定义
3.1 系统边界
解释:
1.对于火车运营系统来讲数据库里的信息是十分宝贵的(当然几乎所有系统的数据库都是十分重要的)所以对于增减火车,更改火车的状态和添加火车站,更改火车的经停表……十分重要的操作都交给 DBA 去做,本系统不提供接口。
2.对于用户来讲分为学生和普通用户,在注册中就进行了区别(学生和普通用户的基本功能完全一致,就是票价计算是学生会有优惠)。
3.在方框内的就是本系统完成的功能。
3.2 用户视图
用户 | 需求 |
---|---|
学生 | 注册(学生验证),登录,购票(直达和换乘),改签(位置,时间),退票和查询(车次经停表,余票和停运车次) |
普通用户 | 注册(无需学生验证),登录,购票(直达和换乘),改签(位置,时间),退票和查询(车次经停表,余票和停运车次) |
DBA(在系统中不与实现,由专业人员录入) | 增添火车更新火车状态添加车站更改火车的经停表 |
四、需求分析
4.1 用户需求说明
4.1.1 功能需求
本系统主要可以实现以下功能:
对火车的售票进行管理。主要功能:车次管理(车次、起止地点、到达时间、开车时间)、每一车次的坐席管理(车厢号、座位号)、售票(直达、换乘等)、改签(更改时间,更改位置)、退票、查询(余票,订单)、用户管理(注册,登录)。
4.1.2 事务需求
1.数据录入
(1)录入火车的基本信息:
火车 id,火车类型,火车状态
(2)录入火车站的基本信息:
火车站 id,火车站所在城市,火车站名称
(3)录入火车座位信息
火车 id,车座 id,火车厢号,座位等级,火车座位位置,出行时间,火车座位状态
(4)录入火车车座表
火车 id,火车站 id,到达时间,等待时间,运行里程
2.系统需要写入的信息
(1)注册用户信息
用户 id,用户 name,用户 password,真实姓名,身份证号,身份信息(是否为学生)
(2)订单产生
订单号,用户 id,火车 id,开始车站,结束车站,车厢号,车座等级,车座位置,出行时间,到开始车站时间,到结束车站时间,车票价格,下单时间
(3)出行时间产生
用户 id,火车 id,出行时间
(4)朋友关系列表
用户 id,用户姓名,朋友 id
3.数据查看说明:数据库必须支持下列查询
(1)查询火车经停站表
(2)查询火车状态
(3)查询火车剩余车座
(4)查询所有开通火车站的城市
(5)查询用户自己的订单
4.数据更新和删除
(1)能够更新朋友表,添加新的朋友
(2)能够更新火车座位表,买票(锁定座位)退票(释放座位)
(3)更新订单表——改签(改变时间或者位置)
(4)删除订单表——退票
4.2 系统需求说明
4.2.1 描述和优先级
用户在注册登录之后,可以自由查询所有开设的火车和所有火车的剩余车票,可以查询指定站点的运行的火车并购买车票,可以通过换乘在两个不直接相通的站点进行来回。可以退票,可以改签,可以查看自己的信息并更新一些信息。
优先级标准:
1.用户体验 2.核心功能 3.实现成本
关键程度标准:
1.核心功能 2.效益和成本 3.用户体验
4.2.2 功能划分
用户的管理:分为注册和登录(分为学生和普通用户)
购票模块:分为直达和换乘
查询模块:分为车次查询,余票查询和暂停运营查询
订单管理:分为退票和改签
总体功能模块图
4.2.3 功能描述
1.系统可以实现对用户的管理——包含用户注册和用户登录。用户注册所需的信息:昵称,身份(学生,非学生),登录密码,真实姓名,身份证号和验证码。用户通过昵称和密码登录。
2.购票模块:用户登录后可以进行购票。购票分为直达购买和换乘购买。系统可以通过起止车站和出行时间准确的获取空的车座,您需要确定的信息——出行时间、车次、起止车站、票种、席别、票价、身份证和真实姓名。
3.查询模块:分为车次查询(查询所有正常运行的火车的经停火车站),余票查询(剩余车座的查询)和暂停运营查询(查询所有暂停运行的火车)
车次查询得到的信息:火车号、经停的火车站、达到时间、在该车站的停止时间和火车已经行驶的路程。
余票查询得到的信息:出行日期、火车号、车座等级和车票剩余。
暂停运营查询得到的信息:停运的火车号和火车类型。
4.订单管理模块:分为退票模块和改签模块。退票——将订单退回。改签可以分为改变位置和改变出行时间。
五、数据库逻辑设计
5.1ER 图
5.2 数据字典
数据库:TrainTicketSystem
实体 | 属性 | 描述 | 键 | 类型及长度 | 是否空 | 是否多值 | 约束 |
---|---|---|---|---|---|---|---|
Users_message | user_id | 唯一表示用户 | 主键 | Int0 | 否 | 否 | 数字表示 |
user_name | 昵称登录使用 | varchar255 | 否 | 否 | |||
user_password | 用户的密码 | varchar255 | 否 | 否 | |||
name | 用户的真实姓名 | varchar255 | 否 | 否 | |||
IDNumber | 用户的身份证号 | varchar255 | 否 | 否 | 必须符合身份证号的固定格式 | ||
stuStatus | 表示用户是否为学生 | tinyint0 | 否 | 否 | 1/0 中一个 | ||
Purchasing_message | user_id | 唯一表示用户 | 主键 | Int0 | 否 | 否 | 必须是 Users_message 中已经存在的 user_id |
user_name | 用户名 | varchar255 | 否 | 否 | |||
purchasing_id | 表示可以帮助购票的 user_id | 主键 | Int0 | 否 | 否 | 必须是 Users_message 中已经存在的 user_id | |
Train_message | train_id | 唯一的标记火车 | 主键 | varchar255 | 否 | 否 | |
train_type | 表示火车的类型 | varchar255 | 否 | 否 | 必须在 G,D,Z 之间选择一个。 | ||
status | 表示火车的状态 | tinyint0 | 否 | 否 | 在 0/1 中选择一个 | ||
Train_seat | train_id | 唯一的标记火车 | 主键 | varchar255 | 否 | 否 | 只能是 Train_message 中出现的 train_id |
seat_id | 唯一标记同一车中的座位号 | 主键 | int0 | 否 | 否 | ||
carriage | 标记车厢号 | int0 | 否 | 否 | 只能在 1/2/3 中选择 | ||
seat_type | 座位等级 | varchar255 | 否 | 否 | 只能在一等座/二等座/三等座中选择 | ||
seat_ocation | 座位位置 | varchar255 | 否 | 否 | |||
ride_time | 乘车时间 | 主键 | varchar255 | 否 | 否 | ||
occupy | 座位是否有人 | smaint0 | 否 | 否 | |||
Train_station | station_id | 唯一表示火车站 | 主键 | int0 | 否 | 否 | |
city | 表示火车站位于那座城市 | varchar255 | 否 | 否 | |||
station_name | 火车站的名称 | varchar255 | 否 | 否 | |||
Stop_tabe | train_id | 唯一表示火车 | 主键 | varchar255 | 否 | 否 | 必须出现在 Train_message 中 |
station_id | 唯一表示火车站 | 主键 | varchar255 | 否 | 否 | 必须出现在 Train_station 中 | |
arrive_time | 表示到站时间 | time | 否 | 否 | |||
stop_time | 表示火车在车站经停时间 | int0 | 否 | 否 | |||
mieage | 表示火车已经行驶的路程 | 主键 | int0 | 否 | 否 | ||
Train_ticket | ticket_id | 唯一表示订单号 | 主键 | int0 | 否 | 否 | |
user_id | 唯一表示用户 | int0 | 否 | 否 | 必须是 Users_message 中已经存在的 user_id | ||
train_id | 唯一表示火车 | varchar255 | 否 | 否 | 必须出现在 Train_message 中 | ||
start_station_name | 起始火车站 | varchar255 | 否 | 否 | 必须出现在 Train_station 中 | ||
end_station_name | 到达火车站 | varchar255 | 否 | 否 | 必须出现在 Train_station 中 | ||
carriage | 车厢号 | varchar255 | 否 | 否 | |||
seat_grade | 车座等级 | varchar255 | 否 | 否 | |||
seat_ocation | 车座位置 | varchar255 | 否 | 否 | |||
ride_time | 出行时间 | varchar255 | 否 | 否 | |||
start_time | 起始时间 | varchar255 | 否 | 否 | |||
end_time | 终止时间 | varchar255 | 否 | 否 | |||
price | 车票价格 | doube10 | 否 | 否 | |||
order_time | 下单时间 | datetime0 | 否 | 否 | |||
Ride_train | user_id | 唯一表示用户 | int0 | 否 | 否 | 必须是 Users_message 中已经存在的 user_id | |
train_id | 唯一表示火车 | varchar255 | 否 | 否 | 必须出现在 Train_message 中 | ||
date | 乘车时间 | varchar255 | 否 | 否 |
5.3 关系模式图
六、数据库物理设计
6.1 索引
MySQ 数据自动为主键创建索引,所以我们只需将那些常用的数据比较多的列名设置索引即可。
1.为用户证件号创建索引
create index IDN on Users_message(IDNumber);
2.为火车座位的车厢号创建索引
create index Carr on Train_seat(carriage);
3.为火车座位的状态位创建索引
create index occu on Train_seat(occupy);
4.为火车站点所在城市创建索引
create index city_name on Train_station(city);
5.为火车站点名称创建索引
create index sta_name on Train_station(station_name);
6.为订单的用户 id 创建索引
create index u_id on Train_ticket(user_id);
6.2 视图
创建一个 stop 视图以便查询换乘信息:
create VIEW Stop as select * from Train_station natural join Stop_table;
系统语句
stop | CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `stop` AS select `train_station`.`station_id` AS `station_id`,`train_station`.`city` AS `city`,`train_station`.`station_name` AS `station_name`,`stop_table`.`train_id` AS `train_id`,`stop_table`.`arrive_time` AS `arrive_time`,`stop_table`.`stop_time` AS `stop_time`,`stop_table`.`mileage` AS `mileage` from (`train_station` join `stop_table` on((`train_station`.`station_id` = `stop_table`.`station_id`)))
6.3 安全机制
系统安全、数据安全
数据安全:
十分重要的数据例如火车信息,火车站信息和火车经停站次表用户均无权限改动,只能查询。
程序内部的任何会引起数据库改动的操作(增删改)均经过了严密的审查判定,以确保数据库的准确性和一致性。
如果用户输入的数据格式不正确,系统将会反馈用户让其重新输入,确保系统数据安全的同时对于初级用户的使用也十分友好。
系统安全:
用户注册需要经过严格的审查,身份证号必须是真实可用的才可以登录系统。
登陆需经过身份认证,即身份口令密码一致才可登录。
退出系统后 Session 随时清除确保系统的安全。
6.4 其他-添加外键约束
1.为 Purchasing_message 表的 user_id,purchasing_id 添加外码依赖
`trainticketsystem`.`purchasing_message`, CONSTRAINT `purchasing_message_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users_message` (`user_id`)`trainticketsystem`.`purchasing_message`, CONSTRAINT `purchasing_message_ibfk_2` FOREIGN KEY (`purchasing_id`) REFERENCES `users_message` (`user_id`)
2.为 Ride_train 表的 user_id,train_id 添加外码依赖
`trainticketsystem`.`ride_train`, CONSTRAINT `ride_train_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users_message` (`user_id`)`trainticketsystem`.`ride_train`, CONSTRAINT `ride_train_ibfk_2` FOREIGN KEY (`train_id`) REFERENCES `train_message` (`train_id`)
3.为 Stop_tabe 表的 train_id,station_id 添加外码依赖
`trainticketsystem`.`stop_table`, CONSTRAINT `stop_table_ibfk_1` FOREIGN KEY (`train_id`) REFERENCES `train_message` (`train_id`)`trainticketsystem`.`stop_table`, CONSTRAINT `stop_table_ibfk_2` FOREIGN KEY (`station_id`) REFERENCES `train_station` (`station_id`)
4.为 Train_seat 表添加外码依赖
`trainticketsystem`.`train_seat`, CONSTRAINT `train_seat_ibfk_1` FOREIGN KEY (`train_id`) REFERENCES `train_message` (`train_id`)
5.为 Train_ticket 表 user_id,train_id,start_station_name,end_station_name 添加外码依赖
`trainticketsystem`.`train_ticket`, CONSTRAINT `train_ticket_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users_message` (`user_id`)`trainticketsystem`.`train_ticket`, CONSTRAINT `train_ticket_ibfk_2` FOREIGN KEY (`train_id`) REFERENCES `train_message` (`train_id`)`trainticketsystem`.`train_ticket`, CONSTRAINT `train_ticket_ibfk_3` FOREIGN KEY (`start_station_name`) REFERENCES `train_station` (`station_name`)`trainticketsystem`.`train_ticket`, CONSTRAINT `train_ticket_ibfk_4` FOREIGN KEY (`end_station_name`) REFERENCES `train_station` (`station_name`)
七、应用程序设计
7.1 功能模块
7.2 界面设计
7.2.1 注册界面
7.2.2 登陆界面
3.主界面
7.2.3 购票界面
直达:
换乘
7.2.4 查询界面
车次
余票查询
停运火车查询
7.2.5 退票和改签界面
退票
改签
7.3 事务设计
关键或复杂的事务操作的设计,附相应 SQ 语句进行分析介绍。
7.3.1 新客户注册
保证不是已注册的客户,保证证件号(主码)不为空,密码输入要一致。
为 IDNumber 创建唯一性约束:
String sql = "insert into Users_message (user_name,user_password,name,IDNumber,stuStatus) values ('"+regisUser.getUser_name()+"','"+regisUser.getUser_password()+"','"+regisUser.getName()+"','"+regisUser.getIDNumber()+"',"+regisUser.getStuStatus()+");";
7.3.2 直达车站查询
通过两个车站锁定火车,注意起始车站的时间要在终止车站之前,即不能“开倒车”。
//2.获取所有符合条件的火车int status = Integer.parseInt(request.getParameter("status"));String startCity = request.getParameter("startStation");String endCity = request.getParameter("endStation");String ride_time = request.getParameter("ride_time");ArrayList list = GetTrain.getTrains(startCity,endCity);public static ArrayList getTrains(String startCity,String endCity){ArrayList list = new ArrayList();/* mysql中并没有intersect和except的语句,获取经过起始城市和终止城市的火车id 同时要确定起始站一定在终止站的前方(防止"倒车的bug")-2020.9.24 */String sql = "select distinct train_id from Train_message natural join Train_station natural join Stop_table as T where " +"city='"+startCity+"' and train_id in (select train_id from Train_message natural join Train_station natural join Stop_table where" +" city='"+endCity+"') and (select max(mileage) from Train_message natural join Train_station natural join Stop_table where" +" city='"+startCity+"' and train_id=T.train_id) < (select max(mileage) from Train_message natural join Train_station natural join Stop_table where city='"+endCity+"' and train_id=T.train_id)and status=1";ResultSet resultSet = JDBCTest.executeQuery(sql);try{while (resultSet.next()){System.out.println("火车号为:"+resultSet.getString(1));String train_id = resultSet.getString(1);Train train = new Train();train.setTrainType(train_id);train.setStartStation(getStation(startCity,train_id));train.setEndStation(getStation(endCity,train_id));train.setSeat1(getSeat(train_id,1));train.setSeat2(getSeat(train_id,2));train.setSeat3(getSeat(train_id,3));System.out.println("火车的始发站是:"+getStation(startCity,train_id));list.add(train);}} catch (SQLException throwables) {throwables.printStackTrace();}return list;}
7.3.3 购买车票产生订单
这个需要做并发控制,必须“同时”向 Ride_train,Train_ticekt 表中添加数据,并且更新 Train_seat 中的数据
//标志位String successful = "OK";for (int i = 0; i < users.size(); i++) {ticket.setCarriage(Integer.parseInt(reCarriages[i+1]));ticket.setSeat_location(reLocations[i+1]);//原子性//将每个得到的人加入车票if (GenerateTicket.insertTicket(ticket,users.get(i).getIDNumber())==-1){successful = "NOT_BUY";}}/*获取车票 */public static int insertTicket(Ticket ticket,String IDNumber){ticket.setPrice(getPrice(ticket,IDNumber));ticket.setUser_id(getUser(IDNumber));String sql = "insert into Train_ticket (user_id,train_id,start_station_name,end_station_name,carriage,seat_grade,seat_location,ride_time,start_time,end_time,price) " +"values ('"+ticket.getUser_id()+"','"+ticket.getTrain_id()+"','"+ticket.getStart_station_name()+"','"+ticket.getEnd_station_name()+"',"+ticket.getCarriage()+","+ticket.getSeat_grade()+"," +"'"+ticket.getSeat_location()+"','"+ticket.getRide_time()+"','"+ticket.getStart_time()+"','"+ticket.getEnd_time()+"',"+ticket.getPrice()+");";String sql2 = "update Train_seat set occupy=0 where train_id='"+ticket.getTrain_id()+"' and carriage="+ticket.getCarriage()+" and seat_location='"+ticket.getSeat_location()+"' and ride_time='"+ticket.getRide_time()+"'";String sql3 = "insert into Ride_train values ('"+ticket.getUser_id()+"','"+ticket.getTrain_id()+"','"+ticket.getRide_time()+"')";String sqls[] = new String[3];sqls[0] = sql;sqls[1] = sql2;sqls[2] = sql3; return Affairs.transaction_control(sqls);}
数据库的并发控制
/*** * 数据库的事务并发控制 */public class Affairs {static Connection conn=null;static {conn=DBConnection.getConnection();}public static inttransaction_control(String sql[]){Statement stmt = null;int result = 0;try {// 开启事务//不把其设置为true之前都是一个当作一个事务来处理conn.setAutoCommit(false);// 创造SQL语句// 执行SQL语句stmt = conn.createStatement();for (int i = 0; i < sql.length; i++) {//System.out.println(i+"*****************");stmt.executeUpdate(sql[i]);}// 提交事务conn.commit();//System.out.println( "OK!" );}//发生任何错误均需回滚catch (SQLIntegrityConstraintViolationException e3) {result = -1;//主码冲突,返回支付失败try {// 回滚事务//撤销上面对事务的所有操作哈!conn.rollback();}catch (SQLException e2){e2.printStackTrace();}} catch (Exception e) {e.printStackTrace();System.out.println("有错误!");try {// 回滚事务//撤销上面对事务的所有操作哈!conn.rollback();}catch (SQLException e2){}}return result;}}
7.3.4 换乘车票的购买
呈现换乘一次车站的 SQ 语句:
String sql = "select a.train_id as first_tid, d.train_id as second_tid, e.train_id as first_tname, f.train_id as second_tname, b.station_id as transfer_station " +"from Stop as a,Stop as b, Stop as c,Stop as d, Train_message as e, Train_message as f " +"where a.city = '"+start_station_city+"' and d.city = '"+end_station_city+"' and a.train_id = b.train_id and b.station_name = c.station_name and c.train_id = d.train_id" +"and a.mileage < b.mileage and c.mileage < d.mileage and b.arrive_time < c.arrive_time " +"and a.train_id not in (select train_id from Train_message where status = '0') and d.train_id not in (select train_id from Train_message where status = '0') " +"and a.train_id = e.train_id and d.train_id = f.train_id;";
解决换乘的 servet
//2.获取所有符合条件的火车String startCity = request.getParameter("startStation");String endCity = request.getParameter("endStation");String ride_time = request.getParameter("ride_time");String seat_type = request.getParameter("ticket_type");ArrayList transferMessages = GetTransfer.getTransferMessage(startCity,endCity);request.getSession(true).setAttribute("transferMessage",transferMessages);request.getSession(true).setAttribute("startStation",startCity);request.getSession(true).setAttribute("endStation",endCity);request.getSession(true).setAttribute("rideTime",ride_time);request.getSession(true).setAttribute("seatType",seat_type);System.out.println(ride_time);response.sendRedirect("http://localhost:8080/TrainTicketingSystem/Transfer.jsp");
7.3.5 用户退票
退票方法:
public static int refund_ticket(int ticket_id, String train_id, int carriage, String location, int user_id, String ride_time){String sql = "delete from Train_ticket where ticket_id="+ticket_id;String sql2 = " update Train_seat set occupy=1 where train_id='"+train_id+"' and carriage="+carriage+" and seat_location='"+location+"' and ride_time='"+ride_time+"'";String sql3 = "delete from Ride_train where user_id="+user_id+" and train_id='"+train_id+"' and date='"+ride_time+"'";//并发控制String sqls[] = new String[3];sqls[0] = sql;sqls[1] = sql2;sqls[2] = sql3;return Affairs.transaction_control(sqls);}
其中 Affairs 也是并发控制,同时决定三个 sq 一同执行,或一同未执行。
Servet 代码:
//2.处理退票int ticket_id = Integer.parseInt(request.getParameter("ticket_id"));String train_id = request.getParameter("train_id");int carriage = Integer.parseInt(request.getParameter("train_carriage"));String location = request.getParameter("train_location");int user_id = Integer.parseInt(request.getParameter("user_id"));String name = request.getParameter("user_name");String ride_time = request.getParameter("ride_time");//标志位String successful = "OK";//原子性//将每个得到的人加入车票if (RefundTicket.refund_ticket(ticket_id,train_id,carriage,location,user_id,ride_time) ==-1){successful = "NOT";}request.getSession(true).setAttribute("successful_refund",successful);ArrayList tickets = GetOrder.getTickets(name);request.getSession(true).setAttribute("orders",tickets);response.sendRedirect("http://localhost:8080/TrainTicketingSystem/UserCenter.jsp");
7.3.6 改签
改签的 SQ 语句:
//1.退票String sql = "delete from Train_ticket where ticket_id="+ticket_id;String sql2 = " update Train_seat set occupy=1 where train_id='"+train_id+"' and carriage="+carriage+" and seat_location='"+location+"' and ride_time='"+ride_time+"'";String sql3 = "delete from Ride_train where user_id="+user_id+" and train_id='"+train_id+"' and date='"+ride_time+"'";//2.添加票ticket.setPrice(getPrice(ticket,IDNumber));ticket.setUser_id(getUser(IDNumber));System.out.println("time3 is not null"+ticket.getRide_time());String sqlTwo = "insert into Train_ticket (user_id,train_id,start_station_name,end_station_name,carriage,seat_grade,seat_location,ride_time,start_time,end_time,price) " +"values ('"+ticket.getUser_id()+"','"+ticket.getTrain_id()+"','"+ticket.getStart_station_name()+"','"+ticket.getEnd_station_name()+"',"+ticket.getCarriage()+","+ticket.getSeat_grade()+"," +"'"+ticket.getSeat_location()+"','"+ticket.getRide_time()+"','"+ticket.getStart_time()+"','"+ticket.getEnd_time()+"',"+ticket.getPrice()+");";String sqlTwo2 = "update Train_seat set occupy=0 where train_id='"+ticket.getTrain_id()+"' and carriage="+ticket.getCarriage()+" and seat_location='"+ticket.getSeat_location()+"' and ride_time='"+ticket.getRide_time()+"'";String sqlTwo3 = "insert into Ride_train values ('"+ticket.getUser_id()+"','"+ticket.getTrain_id()+"','"+ticket.getRide_time()+"')";//并发控制String sqls[] = new String[6];sqls[0] = sql;sqls[1] = sql2;sqls[2] = sql3;sqls[3] = sqlTwo;sqls[4] = sqlTwo2;sqls[5] = sqlTwo3;return Affairs.transaction_control(sqls);
也需要并发控制 6 条 SQ 语句的执行
处理改签的 servet:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.设置编码//终极版简单的方式设置编码,解决乱码问题告诉浏览器你用的字符编码方式request.setCharacterEncoding("utf-8");//终极版简单的方式设置编码,解决乱码问题告诉浏览器你用的字符编码方式response.setContentType("text/html;charset=utf-8");String changeWhat = request.getParameter("changeWhat");if (changeWhat.equals("time")){//2.更改车票时间的处理int ticket_id = Integer.parseInt(request.getParameter("ticket_id"));String train_id = request.getParameter("train_id");int carriage = Integer.parseInt(request.getParameter("train_carriage"));String location = request.getParameter("train_location");int user_id = Integer.parseInt(request.getParameter("user_id"));String name = request.getParameter("user_name");String ride_time = request.getParameter("ride_time");//更改前的出行时间String ride_time_change = request.getParameter("ride_time_change");//更改后的出行时间String start_station_name = request.getParameter("start_station_name");String end_station_name = request.getParameter("end_station_name");int seat_grade = Integer.parseInt(request.getParameter("seat_grade"));System.out.println("time1"+ride_time);System.out.println("time2"+ride_time_change);Ticket ticket = new Ticket();ticket.setTrain_id(train_id);ticket.setStart_station_name(start_station_name);ticket.setEnd_station_name(end_station_name);ticket.setSeat_grade(seat_grade);ticket.setRide_time(ride_time_change);ticket.setStart_time(GenerateTicket.getTime(train_id,start_station_name));ticket.setEnd_time(GenerateTicket.getTime(train_id,end_station_name));ticket.setSeat_location(location);ticket.setCarriage(carriage);//标志位String successfulChangeTime = "OK";//原子性//退票加买票必须同时完成或者都不完成if (ChangeTicket.changeTime(ticket_id,train_id,carriage,location,user_id,ride_time,ticket, GetPeople.getIDNumber(name))==-1){successfulChangeTime = "No";}ArrayList tickets = GetOrder.getTickets(name);request.getSession(true).setAttribute("orders",tickets);request.getSession(true).setAttribute("successfulChangeTime",successfulChangeTime);response.sendRedirect("http://localhost:8080/TrainTicketingSystem/UserCenter.jsp");}else if (changeWhat.equals("location")){ //更改位置的处理int ticket_id = Integer.parseInt(request.getParameter("ticket_id"));String train_id = request.getParameter("train_id");String ride_time = request.getParameter("location_ride_time");int carriage_old = Integer.parseInt(request.getParameter("carriage_old"));String location_old = request.getParameter("location_old");intcarriage_new = Integer.parseInt(request.getParameter("carriage_new"));String location_new = request.getParameter("location_new");String IDNumber = request.getParameter("IDNumber");String successfulChangeLocation = "OK";if (ChangeTicket.changeLocation(ticket_id,train_id,ride_time,carriage_old,location_old,carriage_new,location_new)==-1){successfulChangeLocation = "No";}String name = GetPeople.getRealName(IDNumber);System.out.println(name);ArrayList tickets = GetOrder.getTickets(name);request.getSession(true).setAttribute("orders",tickets);request.getSession(true).setAttribute("successfulChangeLocation",successfulChangeLocation);response.sendRedirect("http://localhost:8080/TrainTicketingSystem/UserCenter.jsp");}else {}}
7.3.7 添加朋友
SQ 语句
String sql = "insert Purchasing_message values ("+user_id_buy+",'"+name_buy+"',"+user_id_friend+")";
Servet 代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.设置编码//终极版简单的方式设置编码,解决乱码问题告诉浏览器你用的字符编码方式request.setCharacterEncoding("utf-8");//终极版简单的方式设置编码,解决乱码问题告诉浏览器你用的字符编码方式response.setContentType("text/html;charset=utf-8");//2.添加新朋友String name_buy = request.getParameter("buy_name");String name_friend = request.getParameter("name");String IDNumber = request.getParameter("IDNumber");int result = AddFriend.addFriends(name_buy,IDNumber);String result_str = result+"";request.getSession(true).setAttribute("results",result_str);request.getSession(true).setAttribute("users",null);response.sendRedirect("http://localhost:8080/TrainTicketingSystem/ConfirmOrder.jsp");}
八、测试和运行
通过测试数据来检验程序的正确性和可用性。
8.1 注册和登录
注册功能正常,如果身份证非法系统会正常给予提示:
正确则正常显示:
登陆一切正常:身份,证件号,密码一致即可,否则报错
8.2 购票
8.2.1 直达火车票购买正常
1)添加朋友正常:
2)查询正常
3)选座正常:
4)购买正常
8.2.2 换乘火车票购买正常
1)查询正常
2)购买正常
8.3 查询正常
查询余票
查询车次表:
查询停运火车:
8.4 退票正常
8.5 改签正常
8.5.1 改变位置正常
8.5.2 改变时间正常
九、总结
选题,当时老师在假期里向我们介绍了这次课程设计的选择题目我对火车售票系统产生了浓厚的兴趣,于是在假期里开始着手了解关于火车售票的一些专业概念——改签,换乘……。在大体了解整个系统的运转模式之后便开始着手设计数据库,因为这次课程设计的主要目的就是锻炼我们的数据库使用能力,于是我花了很大的精力在数据库的设计上,通过 ER 图模式实现了数据库符合三范式。之后进行建表写程序。程序是基于 JSP 的 webapp,因为大二时我曾经做过 webapp 课程设计,对 Web 开发有一定的基础。并且我对 12306 的购票网站印象深刻,打算模拟 12306 的模式创建一个 webapp。
通过2个月的努力,终于完成了数据库课程设计。通过这次课程设计着实提高了我对数据库的深入了解。我使用的是MySQ数据库,MySQ作为一款开源的数据库,同时是一个关系型数据库管理系统,由瑞典MySQAB公司开发,目前属于Orace公司。MySQ是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。之前的Java课程设计,web课程设计我都是使用的这款数据库。但这次我是深入的了解了MySQ数据库的使用,比如MySQ并不支持集合并语句,MySQ数据库上创建视图,创建索引,创建外键依赖……
我设计的这个程序可以实现购票,改签,退票,查询功能,对于用户的注册和登录也能很好的实现。但是受制于精力我的系统也存在一些缺陷,比如我并没有设置修改密码这一功能,还有就是只能购买四天之内的火车票。
我觉得这次课程设计我最大的收获在于增强了自己解决实际问题的能力,面对这次课程设计中不断的出现问题,我会静下心来耐心的找bug,看看到底是语法的错误还是逻辑的错误,有时是在找不出就会上网查询、搜寻资料……在不断的改进过程中,深刻的认识到自己程序的bug,最可怕的是嵌在程序中的SQ语句发生错误,比如,如果是中文格式下的逗号,系统不会正确执行SQ语句,之后我就每次先在终端上执行一遍SQ语句再放到程序中,大大降低了错误率。通过这次设计,不但让我进一步加深了对数据库知识的掌握,而且很好的锻炼了我的独立思考能力,以及分析问题解决问题的能力。数据库在软件界的复杂程度应该是仅次于操作系统的,通过这次课程设计我对这句话有了更加深刻的了解,更感到掌握数据库知识的重要性。以后的学习中会更加努力的学习数据库知识,提升自己的能力。
♻️ 资源
大小: 64.4MB
➡️ 资源下载:https://download.csdn.net/download/s1t16/87379031