演示视频:
https://www.bilibili.com/video/BV1SN4y1x7K7/
3.1 公交查询系统的需求
3.1.1 系统需求描述
公交查询系统的需求最主要是通过站点与车次之间的关系,利用数据结构算法构造一个公交查询的网络图,然后通过最短路径算法,为用户准确地提供两站点之间的最短乘车路线。
其次从业务实现上来说,需要在业务逻辑层上编写最短路径算法,同时还要编写当用户查询请求时必须的数据库连接,然后根据用户提供查询站点信息,建立公交查询网络图,最终调用算法获取两站点之间的最短乘车线路。当查询完成后,如果用户需要进行其它的操作,则释放该连接资源。
最后,为了让公交线路信息得到及时的更新或是信息删除,需要做出相应的操作和处理。
3.1.2 系统数据流图
图3.1 系统数据流图
3.2 公交查询系统的功能
(1)通过选择商厦名称进行相应的信息查询。
(2)通过选择车号进行相应的信息查询。
(3)通过选择站点进行相应的信息查询。
(4)通过选择任意两个站点,完成两站点之间最短乘车路线查询。
(5)完成车次和站点添加功能。
(6)完成车次和站点更新功能。
(7)完成车次和站点删除功能。
(8)用户登录验证功能。
(9)用户注册信息功能。
(10)用户注销功能。
(11)删除用户信息功能。
(12)添加用户留言,删除用户留言,查看用户留言。
(13)管理员登录验证功能。
(14)管理员注销功能。
3.3 公交查询系统的数据库设计
3.3.1E-R图
图3.2 用户实体及属性
图3.3 管理员实体及属性
图3.4 留言板实体及属性
图3.5 车次与站点之间关系
4 公交查询系统的设计与实现
3.1 创建管理员登录的Servlet
(1)打开Eclipse开工具,新建一个ConfirmServlet类(如图3.1)
图3.1 创建管理员登录ConfirmServlet类
(2)在已创建好ConfirmServlet类中,生成一个具有私有属性的login()方法,该方法就是对管理员请求过来的信息进行验证。该方法首先利用HttpServletRequest,HttpServletResponse进行对象初始化。利用HttpServletRequest的getParameter()来获取管理员页面传来的两个参数,一个是adminname,另一个是adminpassword。然后调用自定义连接数据库类进行数据库对象实例化,最后在进行验证的时候,获取管理页面验证码,如果验证码无误就对管理员账号和管理员密码验证,最终将正确的管理员账号和管理员密码放入session会话变量中。
管理员登录界面(如图3.2)
图3.2 管理员登录界面
3.2 创建用户登录的Servlet
(1)打开Eclipse开工具,新建一个UserLoginServlet类(如图3.3)
图3.3 创建用户登录UserLoginServlet类
(2)与管理员中的ConfirmServlet类一样,也生成一个具有私有属性的login()方法,该方法也同样的继承了HttpServletRequest和HttpServletResponse类,通过这个类来获取用户界面请求过来的参数,当通过用户信息验证后,同样也将用户账号和用户的密码放入session会话变量中,一旦用户最终关闭浏览器,session会话变量也随即销毁。
用户登录界面(如图3.4)
图3.4 用户登录界面
3.3 公交系统查询模块
3.3.1 车次信息查询
车次信息查询是为用户提供一个按公交车的车号(如:1路)查询,并显示该公交车的相关信息(如:公交车的起点站、终点站、票价和车子的档次等信息)。而查询功能的实现是由系统的业务逻辑层中的QueryData类来实现的。
车次信息查询结果(如图3.6)
图3.6 车次信息查询
调用此方法时,在页面中先引用包com.busSystem.util,再创建QueryData类的对象,通过对象调用statisticsByBusInfo()这个方法。
3.3.2 站点信息查询
站点信息查询是为用户提供按公交车某一个站点查询到该站点需要乘坐公交车的车号。该查询功能的实现也是由系统的业务逻辑层中的QueryData类来实现的。
站点信息查询结果(如图3.7)
图3.7 站点信息查询
调用此方法时,在页面中先引用包com.busSystem.util,再创建QueryData类的对象,通过对象调用queryStInfo()这个方法。
3.3.3 两个站点间的信息查询
任意两个站点间的查询页面(如图3.8)
图3.8 最短路径查询页面
任意两个站点间查询结果页面(如图3.9)
图3.9 任意两个站点间查询结果
(1)广度优先遍历概念
给定一个起点,广度优先遍历首先访问起点与起点的邻接点,然后分别考察每一个邻接点并访问它们的邻接点。遍历使用一个队列存放顶点的未被访问邻接点,每当从队列中删除一个顶点,就将这个顶点的未访问邻接点插入队列,遍历的顺序即为顶点插入这个队列的顺序。
(2)图的建立过程
图3.10 构造图的流程
①初始化车次列表listBusNum,它是用来存储数据库中现有的车号,为建立图的先做好准备。
②在建立图的过程需要连接数据库,所以必须将需要用到连接数据库的类全部对象初始化,如:connection,statement,resultset这三个关键类。
③首先建立图的时候,需要添加图的各个节点。而这里的节点就是数据库站点信息(stinfo)表中的站点ID号。
④查询站点信息表,将所有的站点从数据库中取出来,调用添加站点graph.addVertex()的方法,将图的各个节点建立好。
⑤通过车次列表,循环的取出各个车号,查询车号与站点ID关系表(busst),找到该车号对应的所有站点。
⑥创建向量vector,该向量用来存放一个车号对应多个站的ID号。
⑦初始化站点列表listStID,它用来存放已经保存好站点ID的向量,这样子就建立起一个关系,就是站点列表中保存了每一个车号所对应车号它自身的所有站点ID。
⑧将站点列表和初始化好了的图一起传入createEdgeByDateBase中,建立双向图。最后图的建立过程结束。
(3)最短路径算法原理图(如图3.11)
图3.11 最短路径算法原理图
(4)最短路径算法原理描述:
①将顶点A入队,同时将顶点A设置为已经被访问。
②判断队列是否为空,如果不是则顶点A出队,同时判断顶点A的邻接顶点B、E、D是否已经被访问,如果没有,则将顶点B、E、D入队,并分别设置为已经被访问,接着将入队顶点B、E、D分别指向他们的前置顶点A,并分别判断顶点B、E、D是否为目的顶点I,不是则进入下一步3。
③判断队列是否为空,如果不是则顶点B出队,同时判断顶点B的邻接顶点E是否已经被访问。判断可知顶点B的邻接顶点E已经被访问,则顶点E不用指向他的前置顶点B。接着进入下一步4。
④判断队列是否为空,如果不是则顶点E出队,同时判断顶点E的邻接顶点F、H是否已经被访问,如果没有,则将顶点F、H入队,并分别设置为已经被访问,接着将入队顶点F、H分别指向他们的前置顶点E,并分别判断顶点F、H是否为目的顶点I,不是则进入下一步5。
⑤判断队列是否为空,如果不是则顶点D出队,同时判断顶点D的邻接顶点G是否已经被访问,如果没有,则将顶点G入队,并分别设置为已经被访问,接着将入队顶点G分别指向他们的前置顶点D,并分别判断顶点G是否为目的顶点I,不是则进入下一步6。
⑥判断队列是否为空,同时判断入队的顶点F是否是目的顶点I。如果不是则顶点F出队,同时判断顶点F的邻接顶点C是否已经被访问,如果没有,则将顶点C入队,并分别设置为已经被访问,接着将入队顶点C分别指向他们的前置顶点F。并分别判断顶点C是否为目的顶点I,不是则进入下一步7。
⑦判断队列是否为空,如果不是则顶点H出队,同时判断顶点H的邻接顶点I是否已经被访问,如果没有,则将顶点I入队,并分别设置为已经被访问,接着将入队顶点I指向他们的前置顶点H,并分别判断顶点I是否为目的顶点I,可以判断顶点I就是目的顶点,将顶点I入堆栈,进入下一步8。
⑧判断I的前置顶点是否为空,如果不是则将前置顶点入堆栈,循环判断前置顶点的前置顶点,如果不为空,则入堆栈,直到循环判断到空为止。这样堆栈中的所有顶点出堆栈,出堆栈的顶点A->E->H->I就是查询出来最短路径。
最短路径算法相应的程序(利用广度优先遍历算法查找最短路径):
3.4 公交系统添加模块
3.3.1 添加车次
添加车次功能主要是增加一个车次详细信息,其中包括:车次号,起点站,终点站,票价,汽车档次,票价类型。需要注意,在添加起点站和终点站的时候,数据都是从站点库获得然后添加到起点站和终点站中去。因为添加车次它只涉及到车次的详细信息,如果要想添加站点,则需要在添加站点功能页面中进行相应的操作。
添加车次页面(如图3.12)
图3.12 添加车次
3.3.2 添加站点
添加站点功能:(1)在添加站点的文本框中输入要添加的站点名称。(2)提供了一个站点重名的查找功能,该功能可以对你输入添加的站点名称进行名称查重,通过查询站点编码表,显示这个站点是否已经存在。如果不存在,则将此新增站点名称插入到站点编码表中,如果存在,则不需将此站点名称插入到站点编码表中。(3)通过下拉选择框选择新增站点所对应的车次号。(4)如果查询站点总数在文本框中显示为“0”,则需要将起点站和终点站同新增的站点一起插入车次和站点的关系表中。如果查询站点总数在文本框中显示不为“0”,则只需将新增的站点插入车次和站点关系表中即可。
添加站点页面(如图3.13)
图3.13 添加站点
3.5 公交系统删除模块
3.3.1 删除车次
删除车次功能:分页列出车次信息表中所有的车次信息,选择操作中的删除,就可以将对应的车次信息删除,但是在删除车次信息的时候需要先删除车次与站点关系表中所有对应该车次的信息。如果不先删除就会出现违反数据库完整性。
删除车次页面(如图3.14)
图3.14 删除车次
3.3.2 删除站点
删除站点功能:通过车次的下拉选择框选择车次,进行查询列出该车次的所有站点信息,然后点击删除操作就可以删除该站点。需要注意:因为在车次中从起点站到终点站计算,其所有的站点是一个有次序的排列,所以删除一个站点,则它的下个站点次序号依次减少一位。
删除站点页面(如图3.15)
图3.15 删除站点
3.6 公交系统更新模块
更新站点功能:通过车次的下拉选择框选择车次,进行查询列出该车次的所有站点信息,然后点击更新操作就可以更新该站点。需要注意的是,在更新起点站(或是终点站)的时候,也要同时更新车次表中的起点站(或是终点站)。
更新站点页面(如图3.16)
图3.16 更新站点
3.7 公交系统留言板模块
3.7.1 发表留言
发表留言是公交查询系统的一个新增的功能,主要是收集用户的留言信息,可以根据用户提供的留言信息或是提出的建议,对系统进行修改和完善。使得系统更加趋于成熟完整。注册的用户登录到发表留言的板块当中,系统会自动提取用户名称,用户只需添上自己的邮箱,发表的主题和内容即可。
发表留言页面(如图3.17)
图3.17 发表留言
3.7.2 查看留言
查看留言很简单为用户提供了一个查看自己的发表的留言,而其它用户是不能看见的。因为系统是一个管理方面的功能较多,所以不会将用户留言信息提供其它的用户查看。
查看留言(如图3.18)
图3.18 查看留言
3.7.3 删除留言
删除留言功能只有管理员才能查看并操作,在删除的显示页面中会将所有的用户留言信息及用户名显示出来。这样也为管理员提供查看哪些用户是非法的发布留言内容。针对这种情况删除该用户。
删除留言页面(如图3.19)
图3.19 删除留言