Java一次返回中国所有省市区三级树形级联+前端vue展示【200ms内】
一、前言
中国省市区还是不少的,省有34个,市有391个,区有1101个,这是以小编的库里的,可能不是最新的,但是个数也差不了多少。
当一次返回所有的数据,并且还要组装成一个三级树,一般的for,会循环34*391*1101
次。这样就是千万级的,加上与数据库交互,你跑半天也跑不完。
最后的处理是组长提供的思路,果然很快。
二、思路
首先:小编的省市区是三张表
第一:我们通过三次IO从数据库中查询出所有省市区的数据,下面在进行for循环组装树形效率就很快了!
第二:为了减少IO交互,我们把刚刚取出来的市和区构建为map<provinceCode,List<City>>
,map<districtCode,List<District>>
,这样效率就上来了!
三、数据库表设计
1. 省
CREATE TABLE `address_province` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`code` char(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`name` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`short_name` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`new_code` char(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`is_latest` tinyint(3) NULL DEFAULT 1 COMMENT '是否是最新地址,0否1是',
`remarks` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`created_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`created_by` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`updated_at` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
`updated_by` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`is_deleted` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '删除标记,0:正常;1:删除',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_code`(`code`) USING BTREE,
INDEX `idx_address_province_name`(`name`) USING BTREE,
INDEX `idx_address_province_short_name`(`short_name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 35 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '地址省' ROW_FORMAT = Dynamic;
2. 市:
CREATE TABLE `address_city` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
`code` char(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`name` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`new_code` char(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`province_code` char(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`is_latest` tinyint(3) NULL DEFAULT 1 COMMENT '是否是最新地址,0否1是',
`remarks` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`created_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`created_by` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`updated_at` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
`updated_by` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`is_deleted` tinyint(3) NULL DEFAULT 0 COMMENT '删除标记,0正常1删除',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_code`(`code`) USING BTREE,
INDEX `idx_address_city_name`(`name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 392 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '地址市' ROW_FORMAT = Dynamic;
3. 区
CREATE TABLE `address_district` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` char(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`name` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`new_code` char(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`city_code` char(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`province_code` char(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`is_latest` tinyint(3) NULL DEFAULT 1 COMMENT '是否是最新地址,0否1是',
`remarks` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`created_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`created_by` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`updated_at` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
`updated_by` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`is_deleted` tinyint(3) NULL DEFAULT 0 COMMENT '删除标记,0正常1删除',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_code`(`code`) USING BTREE,
INDEX `idx_address_district_name`(`name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3110 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '地址县/区' ROW_FORMAT = Dynamic;
数据量太大了,就不给大家了!
四、具体实现
省市区的实体类就不展示了,大家根据自己公司的设计稍微改动即可使用!
1. 树形VO
/**
* 地址业务父子
*
* @author wangzhenjun
* @date 2022/9/2 16:26
*/
@Data
public class AddressVO implements Serializable {
/**
* ID
*/
@ApiModelProperty(value = "ID")
private Integer id;
/**
* 编码
*/
@ApiModelProperty(value = "")
private String code;
/**
* 名称
*/
@ApiModelProperty(value = "")
private String name;
/**
* 父编码
*/
private String parentCode;
/**
* 市区
*/
private List<AddressVO> children;
}
2. 具体实现
@Override
public Result address() {
long l = System.currentTimeMillis();
// 获取省市区
List<AddressProvince> provinceList = addressProvinceMapper.selectList(Wrappers.<AddressProvince>lambdaQuery().eq(AddressProvince::getIsDeleted, 0).eq(AddressProvince::getIsLatest, 1));
List<AddressCity> cityList = addressCityMapper.selectList(Wrappers.<AddressCity>lambdaQuery().eq(AddressCity::getIsDeleted, 0).eq(AddressCity::getIsLatest, 1));
List<AddressDistrict> districtList = addressDistrictMapper.selectList(Wrappers.<AddressDistrict>lambdaQuery().eq(AddressDistrict::getIsDeleted, 0).eq(AddressDistrict::getIsLatest, 1));
// 按照省code进行分组
Map<String, List<AddressCity>> cityMap = cityList.stream().collect(Collectors.groupingBy(AddressCity::getProvinceCode));
// 按照市code进行分组
Map<String, List<AddressDistrict>> districtMap = districtList.stream().collect(Collectors.groupingBy(AddressDistrict::getCityCode));
List<AddressVO> result = new ArrayList<>();
for (AddressProvince province : provinceList) {
// 获取某个省下的所有市
List<AddressCity> addressCityList = cityMap.get(province.getCode());
// 给树形对象赋省的数据
AddressVO addressProvinceVO = new AddressVO();
addressProvinceVO.setId(province.getId());
addressProvinceVO.setCode(province.getCode());
addressProvinceVO.setName(province.getName());
List<AddressVO> cityResult = new ArrayList<>();
for (AddressCity addressCity : addressCityList) {
// 获取某个市下的所有区
List<AddressDistrict> addressDistrictList = districtMap.get(addressCity.getCode());
// 给树形对象赋市的数据
AddressVO addressCityVO = new AddressVO();
addressCityVO.setId(addressCity.getId());
addressCityVO.setCode(addressCity.getCode());
addressCityVO.setName(addressCity.getName());
addressCityVO.setParentCode(province.getCode());
List<AddressVO> districtResult = new ArrayList<>();
// 便利每个市下面的所有区
for (AddressDistrict addressDistrict : addressDistrictList) {
// 给树形对象赋区的数据
AddressVO addressDistrictVO = new AddressVO();
addressDistrictVO.setId(addressDistrict.getId());
addressDistrictVO.setCode(addressDistrict.getCode());
addressDistrictVO.setName(addressDistrict.getName());
addressDistrictVO.setParentCode(addressCity.getCode());
districtResult.add(addressDistrictVO);
}
addressCityVO.setChildren(districtResult);
cityResult.add(addressCityVO);
}
addressProvinceVO.setChildren(cityResult);
result.add(addressProvinceVO);
}
System.out.println(System.currentTimeMillis() - l);
return Result.success(result);
}
4. 计算时长
我们可以看到,一共297毫秒,小编的机器比较卡,支持cpu在60%情况下,200ms应该问题不大,可以放到redis缓存起来,这样减少IO交互,减少数据库的压力!!
五、前端vue
此时address为数组,按序放了选择的value,
props:可以指定显示和选择的名称,默认是value和label
<el-cascader
v-model="addReceiverForm.address"
placeholder="请选择收货人地址"
:options="options"
:props="{checkStrictly: true,value:'code',label:'name'}"></el-cascader>
========data:============
addReceiverForm:{
address:[]
}
options: [],
========method:============
// 获取省市区
initAddress() {
listAddressAndChild().then(data => {
this.options = data.data
}).catch(() => {
});
},
六、总结
如果大家有比小编更加快的方式,欢迎留言交流哈!
如果觉得有用,还请动动大家的发财小手点点关注哈!!谢谢大家了!!
有缘人才可以看得到的哦!!!
欢迎大家关注小编的微信公众号,谢谢大家!
Java一次返回中国所有省市区三级树形级联+前端vue展示【200ms内】的更多相关文章
- jquery省市区三级联动(数据来源国家统计局官网)内附源码下载
很久很久没有写博了. 今天更新了项目的省市区三级联动数据,更新后最新的海南三沙都有,分享给所有需要的小伙伴们... JQUERY + JSON,无数据库,纯JS代码,无加密,无压缩,可直接使用在任何项 ...
- excel省市区三级分类级联
前言:同事正好需要一个这样的地址类型给用户使用下载模板,改好地址再导入,这样就不会出现地址不匹配问题.所以就自己也整理了一套,以备不时之需. 效果展示: 图一:省级 图二:市级 图三:区级 图四:各乡 ...
- jquery省市区三级联动
jquery省市区三级联动(数据来源国家统计局官网)内附源码下载 很久很久没有写博了. 今天更新了项目的省市区三级联动数据,更新后最新的海南三沙都有,分享给所有需要的小伙伴们... JQUERY + ...
- java的JCombobox实现中国省市区三级联动
源代码下载:点击下载源代码 用xml存储中国各大城市的数据. xml数据太多了就不贴上了,贴个图片: 要解释xml,添加了一个jdom.jar,上面的源代码下载里面有. 解释xml的类: packag ...
- Java学习-058-Jsoup爬虫获取中国所有的三级行政区划数据(三),处理二级编码缺失
通过查看数据可知,直辖市或者某些三级行政区域没有对应的二级区域,为方便后续的地址使用,可自定义缺失的二级地址. 如下示例自定义的二级行政区域的名称为一级区域的名称,对应的源码如下所示: 将此段源码添加 ...
- 项目总结01:JSP mysql SpringMvc下中国省市县三级联动下拉框
JSP mysql SpringMvc下中国省市县三级联动下拉框 关键词 JSP mysql数据库 SpringMvc ajax Controller层 Service层 中国地区 省 ...
- 用jsp实现省市区三级联动下拉
jsp+jquery实现省市区三级联动下拉 不少系统都需要实现省市区三级联动下拉,像人口信息管理.电子商务网站.会员管理等,都需要填写地址相关信息.而用ajax实现的无刷新省市区三级联动下拉则可以改善 ...
- ajax省市区三级联动
jdbc+servlet+ajax开发省市区三级联动 技术点:jdbc操作数据库,ajax提交,字符拦截器,三级联动 特点:局部刷新达到省市区三级联动,举一反三可以做商品分类等 宗旨:从实战中学习 博 ...
- Android中使用开源框架citypickerview实现省市区三级联动选择
1.概述 记得之前做商城项目,需要在地址选择中实现省市区三级联动,方便用户快速的填写地址,当时使用的是一个叫做android-wheel 的开源控件,当时感觉非常好用,唯一麻烦的是需要自己整理并解析省 ...
随机推荐
- websocket心跳实现
简介 在实际项目中可能会使用到websocket,在使用过程中可能会存在一种问题就是,当网络异常断开时.或者websocket服务波动时,websocket会断开,导致异常,正常情况下,我们会采用心跳 ...
- qbxt五一数学Day1
目录 I. 基础知识 1. 带余除法(小学) 1. 定义 2. 性质 2. 最大公约数(gcd)/ 最小公倍数(lcm) 1. 定义 2. 性质 3. 高精度 II. 矩阵及其应用 1. 定义 2. ...
- PLC转OPC UA的协议转换网关需要多少钱呢?
嵌入式OPC UA网关BL102简化了OPC UA程序的开发与IIOT工业物联网应用 在制造业数字化升级过程中,我们碰到最多的工作便是针对每一款PLC去开发一套OPC UA程序,然后通过这套程序去读取 ...
- 封装Fraction-分数类(C++)
Fraction 分数类 默认假分数,可自行修改 由于concept的原因 template <typename T> concept is_float_v = std::is_float ...
- GreatSQL MGR FAQ
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 目录 0. GreatSQL简介 1. GreatSQL的特色有哪些 2. Gr ...
- python包合集-cffi
一.cffi cffi是连接Python与c的桥梁,可实现在Python中调用c文件.cffi为c语言的外部接口,在Python中使用该接口可以实现在Python中使用外部c文件的数据结构及函数. 二 ...
- ModelBox开发体验:使用YOLOv3做口罩检测
摘要:本案例将在ModelBox中使用YOLO v3模型,实现一个简单的口罩检测应用 本文分享自华为云社区<ModelBox开发体验Day05开发案例-使用YOLOv3做口罩检测>,作者: ...
- 【Java】学习路径50-线程死锁问题
生活化的例子:比如说有两个人,一把刀和一把叉子: 第一个人先需要一把刀,然后还需要一把叉子: 第二个人先需要一把叉子,然后还需要一把刀. 我们理想的情况是:一个人拿着刀,然后再拿到叉子,把事情做完,然 ...
- Ansible_基础模块
特点:无主从,即装即用,基于ssh 安装ansible yum install epel-release -y yum install ansible -y 定义主机清单 vim /etc/ansib ...
- 第六章:Django 综合篇 - 9:序列化 serializers
Django的序列化工具让你可以将Django的模型'翻译'成其它格式的数据.通常情况下,这种其它格式的数据是基于文本的,并且用于数据交换\传输过程. 一.序列化数据 Django为我们提供了一个强大 ...