Java后台以树形结构返回省市区三级区域信息

欢迎访问个人博客德鲁大叔撸代码
在前台页面很常见的一种需求是,以树形结构展示具有层级关系的数据。比如企业的部门信息、大部分管理系统的菜单、省市区信息等等。
具体如下图所示
Java后台以树形结构返回省市区三级区域信息_第1张图片
Java后台以树形结构返回省市区三级区域信息_第2张图片

一、表创建以及数据导入

执行下面创建表sql,创建sys_region存具体信息,表信息下载地址sys_region 行政区域表

CREATE TABLE `sys_region`  (
  `id` int(11) NOT NULL COMMENT '区域主键',
  `name` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '区域名称',
  `pid` int(11) NULL DEFAULT NULL COMMENT '区域上级标识',
  `sname` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地名简称',
  `level` int(11) NULL DEFAULT NULL COMMENT '区域等级',
  `citycode` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '区域编码',
  `postcode` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮政编码',
  `mername` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '组合名称',
  `lng` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '经度',
  `lat` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '纬度',
  `pinyin` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '拼音',
  `gmt_create` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `gmt_modified` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改时间',
  `status` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT '状态 0正常 1停用',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

二、编写Region实体类(mybatis generator自动生成后增加子区域属性)

@Data
public class Region {
    private Integer id;

    private String name;

    private Integer pid;

    private String sname;

    private Integer level;

    private String citycode;

    private String postcode;

    private String mername;

    private String lng;

    private String lat;

    private String pinyin;

    private Date gmtCreate;

    private Date gmtModified;

    private String status;

    /**
     * 子区域
     */
    private List children = new ArrayList<>();
}

三、查询接口和mybatis映射文件(省略,只展示查询sql)


四、组装树形菜单(根据步骤三查到的列表)

1、控制转发层

@RestController
@RequestMapping("/region")
public class RegionController {


    @Autowired
    private RegionService regionService;
    @GetMapping("/list")
    public AjaxResult list(Region region){
        List regionList = regionService.selectRegionList(region);  // 根据步骤三查到的集合(region表的全部数据)
        List tree = regionService.buildAreaTree(regionList);   // 组装一个菜单树
        return AjaxResult.success(tree);                     // 响应返回给前端页面的数据
    }

}

2、组装树形菜单入口

 @Override
    public List buildAreaTree(List regions) {
        List tree = new ArrayList<>();
        for(Iterator it = regions.iterator();it.hasNext();){
            Region region = (Region) it.next();
            if(region.getPid() == 0){
                recursionFn(regions, region);  //递归列表
                tree.add(region);
            }
        }
        return tree;

3、递归列表

 /**
     * 递归列表
     * @param list
     * @param region
     */
    private void recursionFn(List list, Region region){
        // 得到子节点列表
        List childList = getChildList(list, region);
        region.setChildren(childList);
        for(Region child : childList){
            if(hasChild(list,child)){
                //判断是否有子节点
                Iterator it = childList.iterator();
                while (it.hasNext()){
                    Region n = (Region) it.next();
                    recursionFn(list, n);
                }
            }
        }
    }

4、得到子节点列表(得到下级区域)

 /**
     * 得到子节点列表
     * @param list
     * @param region
     * @return
     */
    private List getChildList(List list, Region region){
        List tlist = new ArrayList();
        Iterator it = list.iterator();
        while (it.hasNext()){
            Region region1 = (Region) it.next();
            if(region1.getPid().longValue() == region.getId().longValue()){
                tlist.add(region1);
            }
        }
        return tlist;
    }

5、判断是否有下级区域

 /**
     * 判断是否有子节点
     * @param list
     * @param region
     * @return
     */
    private boolean hasChild(List list, Region region)
    {
        return getChildList(list, region).size() > 0 ? true : false;
    }

五、postman测试

以省/直辖市为根节点,组装结果35
Java后台以树形结构返回省市区三级区域信息_第3张图片
以陕西省为例,展示具体的市级信息
Java后台以树形结构返回省市区三级区域信息_第4张图片

你可能感兴趣的:(kyrieboot)