仍旧是关于毕设

到实际开始做的时候才发现要做的东西多麻烦……既需要了解 Spring 的使用,也需要了解前端页面各种库和 webpack 的使用……

后端使用 Soring Boot+Mybatis,因为系统比较复杂,所以分离 entity 层和 domain 层,其中 entity 层代表表中实体,其中包括 bus,place,busline,driver,station,pos,administrator。domain 层则是借助 entity 层,同时利用 bus_line,line_place 和 driver_bus 三个表达前述实体表关系的表以给出前端(实际上是 service 层)所需要的数据实体。dao 层则利用 entity 和 domain 层提供给 service 层操作数据的接口。(这时,entity 层和 domain 层实际上是属于同一层的……需不需要将它们结合呢……)

domain 层也可以去利用 SQL 的视图功能,优点在于只需要对视图进行操作。但是我不知道这实现难度如何,符不符合业务需要……只能说自己菜,还没接触到这些(不如说也不想去了解这些啊……)

现在,至关重要的是去开一个头!使用所谓的“敏捷开发”的方式吧,先整出东西来,再不断迭代——

step1

第一步是完成公交车信息的展示,具体来说有以下需求(使用!标记难度,从低到高分为 1 到 5 个!)——

后端

  • 数据库中实体的设计(出于使用的需要,这一步就需要数据库的设计满足所有功能)(!)
  • entity 层及与当前步骤相关的 mapper 的实现(对应数据库中实体)(!)
  • 数据库中视图的实现(!!)(或许可以不实现)
  • domain 层中与当前步骤相关的实现及其 mapper(对应数据库中视图)(!!)
  • dao 层中相关功能的实现(!!)
  • 支持返回某市区县的公交车之前一段时间的速度和位置功能和不断更新该信息的功能的 websocket 的实现(!!!)
  • 实时接受公交车所发送的信息的 websocket 的实现(!)
  • 公交车模拟模块的实现(!)

前端

  • 展示某市区县的所有公交车实时信息功能的实现(只需实现最基本的展示轨迹。站点,轨迹等功能随后实现)(!!!)

step2

这一步需要完成前端对数据(站点,节点……)的增删改查,同时完全完成上一步的展示实时信息功能。

后端

  • 完成所有查询功能(!!!)
  • 完成登录的需求(!)
  • 完成增删改的需求(!!!)

前端

  • 完成登录功能(!)
  • 完成查询功能(!!!)
  • 完成增删改功能(非常困难!整个项目最困难的地方!同时也应当是项目的亮点所在)(!!!!!)

step3

然后是查询某日历史信息的实现。

后端

  • 展示某市区县公交车某日所有信息功能的实现(!!!)

前端

  • 展示某市区县公交车某日所有信息功能的实现(!!!)

step4

进一步增强前端数据可视化的功能,提供热力图等玩意,以追踪特定时间或特定位置超速情况。

后端

  • 完成所有设计(!!!)

前端

  • 完善数据可视化功能(!!)
  • 完成生成 CSV 文件功能(!)

现在只能给出粗略的要求,每一个步骤需要在前一个步骤的基础上进行研究实现。

首先是建表,考虑到查询之前数据的需要,表中数据必须存储一个时间戳,即使第一步并不提供管理的功能。

思考和多次更改后得出这样的表结构(仍旧可能更改)——

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
-- 对应公交车的表
CREATE TABLE bus (
bus_id INT AUTO_INCREMENT,
bus_number VARCHAR(7) NOT NULL, -- 车牌号,长度为 7 位,形如豫 A99999
bus_type VARCHAR(20) NOT NULL, -- 车型
update_time TIMESTAMP DEFAULT NOW(),
PRIMARY KEY (bus_id, update_time)
);

-- 对应各个区域的表
CREATE TABLE place (
place_id INT AUTO_INCREMENT,
place_name VARCHAR(10) NOT NULL,
lat DECIMAL NOT NULL,
lont DECIMAL NOT NULL,
update_time TIMESTAMP DEFAULT NOW(),
PRIMARY KEY (place_id, update_time)
);

-- 对应公交车线路的表
CREATE TABLE busline (
line_id INT AUTO_INCREMENT,
/*
data_map 是一个相当复杂的数据。它是 json 格式的。
它应当保存途径的路段 id,站点 id,以这样的格式存储——
{
data:[
["nodepath", nodepath_id],
["station", station_id],
["nodepath", nodepath_id],
...
]
}
*/
data_json TEXT NOT NULL,
update_time TIMESTAMP DEFAULT NOW(),
PRIMARY KEY (line_id, update_time)
);

-- 对应驾驶员的表
CREATE TABLE driver (
driver_id INT AUTO_INCREMENT PRIMARY KEY,
update_time TIMESTAMP DEFAULT NOW(), -- 实为上传 (upload) 时间。driver 的信息显然是即使更改也不随时间变化的
driver_name VARCHAR(10) NOT NULL,
driver_sex BIT NOT NULL,
driver_birthday DATE NOT NULL
);

-- 对应公交车站点的表
-- 创建站点时,同时创建一个位于此位置的 node!
CREATE TABLE station (
station_id INT AUTO_INCREMENT,
update_time TIMESTAMP DEFAULT NOW(),
lat DECIMAL NOT NULL,
lont DECIMAL NOT NULL,
PRIMARY KEY (station_id, update_time)
);

-- 对应公交车发送信息(当前位置,车辆 ID)的表
CREATE TABLE pos(
bus_id INT,
update_time TIMESTAMP DEFAULT NOW(),
speed TINYINT NOT NULL, -- 速度——公里每小时(迈),tinyint 存储 0~255 的数字
lat DECIMAL NOT NULL,
lont DECIMAL NOT NULL,
PRIMARY KEY (bus_id, update_time),
FOREIGN KEY (bus_id) REFERENCES bus(bus_id)
);

-- 管理员的表
CREATE TABLE administrator(
admin_id VARCHAR(32) PRIMARY KEY, -- 用作登录
admin_passwd VARCHAR(32) NOT NULL, -- 可以不存储明文
admin_name VARCHAR(32) NOT NULL
);

-- 对应路段节点的表(将被路段表使用)
-- 节点和路段表
CREATE TABLE node(
node_id INT AUTO_INCREMENT,
update_time TIMESTAMP DEFAULT NOW(),
lat DECIMAL NOT NULL,
lont DECIMAL NOT NULL,
PRIMARY KEY (node_id, update_time)
);

-- 对应路段的表
CREATE TABLE nodepath(
nodepath_id INT AUTO_INCREMENT,
update_time TIMESTAMP DEFAULT NOW(),
node1_id INT,
node2_id INT,
speed_limit TINYINT NOT NULL,
direction TINYINT NOT NULL, -- 方向,由南向北逆时针方向为顺向,0 为顺向,1 为逆向,2 为双向
street_name VARCHAR(10) NOT NULL,
PRIMARY KEY(nodepath_id, update_time),
FOREIGN KEY (node1_id) REFERENCES node(node_id),
FOREIGN KEY (node2_id) REFERENCES node(node_id)
);

-- 分割线分割线分割线

-- 公交车线路同公交车的对应的表
-- 一条公交车线路上有多个公交车,一个公交车可能跑多个线路(虽然稀有,但不能说没有)
CREATE TABLE bus_line (
line_id INT,
update_time TIMESTAMP DEFAULT NOW(),
bus_id INT,
PRIMARY KEY (line_id, update_time, bus_id),
FOREIGN KEY(bus_id) REFERENCES bus(bus_id),
FOREIGN KEY(line_id) REFERENCES busline(line_id)
);

-- 公交车线路所处于的位置(一般来说只为同一个位置,但跨区的线路有多个)
-- 与之前的想法不同(通过位置确定所需站点,再通过站点确定线路),选择直接通过位置确定线路。
CREATE TABLE line_place (
line_id INT,
update_time TIMESTAMP DEFAULT NOW(),
place_id INT,
PRIMARY KEY (line_id, update_time, place_id),
FOREIGN KEY (place_id) REFERENCES place(place_id)
);

-- 公交车的驾驶员,一个驾驶员可能可以驾驶多个公交车,一个公交车可能可以由多个驾驶员驾驶
CREATE TABLE driver_bus (
driver_id INT,
update_time TIMESTAMP DEFAULT NOW(),
bus_id INT,
PRIMARY KEY (driver_id, update_time, bus_id),
FOREIGN KEY (driver_id) REFERENCES driver(driver_id),
FOREIGN KEY (bus_id) REFERENCES bus(bus_id)
);

下一步是完成对应的 dao 和 domain……


当前完成了 websocket,service,servlet 的框架,直接更改其内容为业务代码即可。(需要学习一下 spring 的注入……不过对于这个项目或需不需要)

当前任务是——编写测试模块(websocket 客户端,或许使用 python 实现。公交车应当发送当前位置的速度,这是应该的,正常的,容易实现的(对公交车上的硬件来说)),编写实时展示当前信息的前端页面。这一步并不需要完成节点,站点,道路显示等功能(之后再实现)


忙活了好久……终于把 webpack 前端弄完了,感觉还是……挺麻烦的。但是似乎也有所感悟,总之将来再配置的时候就不会这么尴尬了(不过我不想干前端,所以还是希望不要再去搞这个了)。

这篇文章不再更新了,另起炉灶。