在某项目中,有这样一个模块,管理着《督导活动》信息,页面效果如下:
我们重点讨论一下这个地点字段。活动的地点是一个四级的级联菜单,甲方要求可以模糊查询,选择北京市朝阳区,可以查询到下属所有街道的活动数据。
设计思路:
第一部分:
四级的政府行政区,是由用户录入管理的,所以需要设计一个政府行政区的表,形成一个树形结构。这个树形结构的数据表需要支持模糊查询、第三范式,所以我们这样设计行政区表:
(我们使用mysql数据库)建表sql如下:
CREATE TABLE `data_area` (
`id` varchar(8) NOT NULL COMMENT '主键',
`pid` varchar(8) DEFAULT NULL COMMENT '父id',
`text` varchar(50) DEFAULT NULL COMMENT '文本',
`delFlag` tinyint(1) DEFAULT '0' COMMENT '状态:0正常_7删除',
`updateDate` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
)
数据举例:
id
|
pid
|
text
|
01
|
|
北京
|
0101
|
01
|
朝阳区
|
010101
|
0101
|
小红门乡
|
010102
|
0101
|
将台
|
01010101
|
010101
|
中海城社区
|
这样设计的好处是:当模糊查询时,用户选择北京朝阳区,区域id是0101,在数据库中查询id是以0101开头的所有数据。
sql条件如下: area_id like '0101%',这种只有一个%的sql条件,查询效率比两个%高
针对行政区,我们开发了管理模块,页面效果如下:
系统初期,需要录入大量数据,所有新增页面是这样设计的:
一次选择父节点后,可以添加多个子节点。
新增时,需要计算id,先统计子节点数量,再生成新的主键id,比较麻烦。
第二部分:
系统中多次用到行政区级联选择,为了避免重复访问行政区数据,我们缓存了行政区数据,这种缓存分为两种,
第一种在服务器缓存了行政区数据,使用的技术(EHCache或radis或servletContext),提供一些方法,根据id返回文本形式的全路径名称
第二种将行政区的数据生成行政区的js文件,js文件中,保存的是json格式的数据,用户在浏览器端,下载一遍行政区数据后,就不再下载了。
但这种js文件出现了一个问题:因为js文件在启动服务器生成,当修改了行政区表数据时,js文件不会生成的。
解决方法:每当修改政区表数据时,js就会重新生成一次。
又出现第二个问题:有的客户端有缓存,当重新生成js文件后,客户端不会重新加载js文件。
解决方法:为js文件加入版本号,当重新生成js文件后,版本号升级。比如引入js的代码是
jsp页面代码如下:
总结:
-
设计一个政府行政区的表,形成一个树形结构。这个树形结构的数据表需要支持模糊查询、第三范式
-
两种形式缓存了行政区数据
-
为行政区设计了通用的组件,支持新增页面,修改页面,查询页面的使用。(其实我们设计了两套通用的组件,一套是同步的,一套是异步的,异步的组件用于手机微信端)
存在问题:
-
010101这样的id设计,每一个节点只能有99个子节点。我们可以使用十六进制,这样两位数字可以保存255个子节点,但控制难度就又增加了
-
如果有频繁的删除操作,99个节点是不够用的,所以设计时,没有设计删除功能,而是禁用功能。
大家思考一下具体的实现细节,把此功能设计到你的项目中。
|