java 构建省市县的三级树

工作中遇到需要构建省市县的三级树结构,这里参考了 https://www.cnblogs.com/shiyun32/p/12104949.html ,非常感谢,非常不错的案例。

我这里需要的数据格式这这样的:

数据库的部分数据如下:

直接上代码,首先创建一个bean类,进行封装数据,(可以直接用Map,但用来比较费劲,我还是采用将数据库中的数据封装到bean 中,更直接些)

public class UnCdeAreaBean implements Serializable {

	private static final long serialVersionUID =  8139867807928157021L;

	/**
	 * 主键6位串
	 */
	private String value; // 这里是数据库中id ,因实际json显示需要改为value

	/**
	 * 名称
	 */
	private String text; // 这里是数据库中name,因实际json显示需要改为text

	/**
	 * 父节点ID
	 */
	private String pid;

	/**
	 * 级别
	 */
	private String numLevel;

	/**
	 * 是否有效  1:有效   0:无效
	 */
	private String isValid;


	private List<UnCdeAreaBean> children = new ArrayList<>();

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}


	//	public String getId() {
//		return this.id;
//	}
//
//	public void setId(String id) {
//		this.id = id;
//	}

//	public String getName() {
//		return this.name;
//	}
//
//	public void setName(String name) {
//		this.name = name;
//	}


	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public String getPid() {
		return this.pid;
	}

	public void setPid(String pid) {
		this.pid = pid;
	}

	public String getNumLevel() {
		return this.numLevel;
	}

	public void setNumLevel(String numLevel) {
		this.numLevel = numLevel;
	}


	public String getIsValid() {
		return this.isValid;
	}

	public void setIsValid(String isValid) {
		this.isValid = isValid;
	}


//	public List<UnCdeAreaBean> getNodes() {
//		return nodes;
//	}
//
//	public void setNodes(List<UnCdeAreaBean> nodes) {
//		this.nodes = nodes;
//	}


	public List<UnCdeAreaBean> getChildren() {
		return children;
	}

	public void setChildren(List<UnCdeAreaBean> children) {
		this.children = children;
	}

	public UnCdeAreaBean(String value, String text, String pid, String numLevel) {
		this.value = value;
		this.text = text;
		this.pid = pid;
		this.numLevel = numLevel;
	}

	public UnCdeAreaBean(){}
}

接下来就是从数据库中获取数据,然后进行封装到上面创建的实体中:

public List<UnCdeAreaBean> getAreaInfoOptimize() {
        // 从数据库中获取地区数据
        String sql = " select t.* from xxx_tab t WHERE t.is_valid = '1' AND t.num_level < 4 ORDER BY t.id  ";
        List<Map<String, Object>> unCdeAreas = this.findForJdbc(sql);

        // 将List<Map<String, Object>> 转成  List<UnCdeAreaBean>
        List<UnCdeAreaBean> UnCdeAreaBeanArrayList = new ArrayList<>();
        unCdeAreas.forEach(map -> {
            UnCdeAreaBean UnCdeAreaBean = new UnCdeAreaBean((String) map.get("ID"),(String) map.get("NAME"),
                    map.get("PID").toString(), String.valueOf(map.get("NUM_LEVEL")));
            UnCdeAreaBeanArrayList.add(UnCdeAreaBean);
        });

        // 创建一个顶层节点
        UnCdeAreaBean root = new UnCdeAreaBean();
        // 构建树结构
        UnCdeAreaBean areaBean = buildNodes(root, UnCdeAreaBeanArrayList);
//        System.out.println("JSON.toJSONString(root) = " +JSON.toJSONString(areaBean));

        List<UnCdeAreaBean> nodes = areaBean.getChildren();
//       System.out.println("List<UnCdeAreaBean> nodes "+JSONArray.toJSONString(nodes));
        
        return nodes;
    }

构建树的代码:

public static UnCdeAreaBean buildNodes(UnCdeAreaBean root, List<UnCdeAreaBean> nodes) {

        // 剩余节点(还没有找到父节点的节点)
        ArrayList<UnCdeAreaBean> remainNodes = new ArrayList<>();
        // 当前节点下的子节点
        ArrayList<UnCdeAreaBean> child = new ArrayList<>();

        Iterator<UnCdeAreaBean> iterator = nodes.iterator();
        while (iterator.hasNext()) {
            UnCdeAreaBean node = iterator.next();
            // 顶层节点 为多个的时候 北京市、天津市、河北省...就是第一层的时候
            if (Objects.equals(node.getNumLevel(), "1")) {
//                root = node;
                child.add(node); // 这里解释一下,我先将北京市、天津市、河北省...添加child 中作为第一层节点。实际中可能还会遇到这种情况:一个超级root顶节点,只是用来展开,没有实际含义的,点击就展开,root下面才是北京市、天津市、河北省... 这种情况就直接放开注释 root = node ,将child.add(node) 注释即可

                continue;
            }
            // 该节点找到了子节点
            if (Objects.equals(root.getValue(), node.getPid())) {
                child.add(node);
            } else {
                // 没有找到子节点
                remainNodes.add(node);
            }
        }
        // 根节点设置子节点
        root.setChildren(child);
        // 每一个节点再去寻找对应的子节点
        root.getChildren().stream().forEach(x -> {
            buildNodes(x, remainNodes);
        });
        return root;
    }

 

PS: 这里我遇到的一个问题,就是实际需要构建的树结构,有多个顶节点,如:北京市、天津市、河北省 等,而 有一个顶节点的,如:中国下面北京市、天津市、河北省,这里省上层还有一个root顶节点中国。不知道有没有说清楚。

我这里直接采用https://www.cnblogs.com/shiyun32/p/12104949.html的中测试数据,说明一下,以便记录。

数据如下:

        第一种情况,有一个顶节点的  xxx公司就是root顶节点      

        menus.add(new Menu("0", "xxx公司", "", "1"));
        menus.add(new Menu("1", "财务部", "0", "2"));
        menus.add(new Menu("2", "人事部", "0", "2"));
        menus.add(new Menu("11", "财务部11", "1", "3"));
        menus.add(new Menu("12", "财务部12", "1", "3"));
        menus.add(new Menu("22", "财务部22", "2", "3"));
        menus.add(new Menu("21", "财务部21", "2", "3"));

   
        第二种情况,多个顶节点的:财务部 和 人事部 并列的顶节点
//        menus.add(new Menu("0", "xxx公司", "", "1"));
        menus.add(new Menu("1", "财务部", "1", "2"));
        menus.add(new Menu("2", "人事部", "2", "2"));
        menus.add(new Menu("11", "财务部11", "1", "3"));
        menus.add(new Menu("12", "财务部12", "1", "3"));
        menus.add(new Menu("22", "财务部22", "2", "3"));
        menus.add(new Menu("21", "财务部21", "2", "3"));

上述举例的数据得到的json

第一种情况结果,有一个顶层节点  xxx公司,然后公司下面 才是 财务部和人事部

{
    "id":"0",
    "level":"1",
    "name":"xxx公司",
    "nodes":[
        {
            "id":"1",
            "level":"2",
            "name":"财务部",
            "nodes":[
                {
                    "id":"11",
                    "level":"3",
                    "name":"财务部11",
                    "nodes":[

                    ],
                    "parentId":"1"
                },
                {
                    "id":"12",
                    "level":"3",
                    "name":"财务部12",
                    "nodes":[

                    ],
                    "parentId":"1"
                }
            ],
            "parentId":"0"
        },
        {
            "id":"2",
            "level":"2",
            "name":"人事部",
            "nodes":[
                {
                    "id":"22",
                    "level":"3",
                    "name":"财务部22",
                    "nodes":[

                    ],
                    "parentId":"2"
                },
                {
                    "id":"21",
                    "level":"3",
                    "name":"财务部21",
                    "nodes":[

                    ],
                    "parentId":"2"
                }
            ],
            "parentId":"0"
        }
    ],
    "parentId":""
}

第二种情况json: 直接就是财务部和人事部 作为顶节点,没有超级root 节点 “xxx公司”

{
    "nodes":[
        {
            "id":"1",
            "level":"2",
            "name":"财务部",
            "nodes":[
                {
                    "id":"11",
                    "level":"3",
                    "name":"财务部11",
                    "nodes":[

                    ],
                    "parentId":"1"
                },
                {
                    "id":"12",
                    "level":"3",
                    "name":"财务部12",
                    "nodes":[

                    ],
                    "parentId":"1"
                }
            ],
            "parentId":"0"
        },
        {
            "id":"2",
            "level":"2",
            "name":"人事部",
            "nodes":[
                {
                    "id":"22",
                    "level":"3",
                    "name":"财务部22",
                    "nodes":[

                    ],
                    "parentId":"2"
                },
                {
                    "id":"21",
                    "level":"3",
                    "name":"财务部21",
                    "nodes":[

                    ],
                    "parentId":"2"
                }
            ],
            "parentId":"0"
        }
    ]
}

如有问题,欢迎交流指正。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现Java后端省市三级级联可以通过以下步骤: 1. 建立数据库表格 建立三个表格,分别是省份表、城市表和区表,每个表格至少应该包含以下字段: 省份表: - 省份ID - 省份名称 城市表: - 城市ID - 城市名称 - 所属省份ID 区表: - 区ID - 区名称 - 所属城市ID 2. 编写Java代码 通过Java代码来实现数据的查询和返回。 首先,需要编写一个接口,定义查询省份、城市和区的方法。接口可以定义如下: ```java public interface AreaService { List<Province> getProvinceList(); List<City> getCityListByProvinceId(String provinceId); List<Area> getAreaListByCityId(String cityId); } ``` 然后,实现上述接口,实现数据查询和返回。可以使用MyBatis、Hibernate等框架来实现。 3. 编写控制器 编写控制器来处理HTTP请求,返回JSON格式的省份、城市和区数据。 ```java @RestController @RequestMapping("/area") public class AreaController { @Autowired private AreaService areaService; @GetMapping("/provinces") public List<Province> getProvinceList() { return areaService.getProvinceList(); } @GetMapping("/cities/{provinceId}") public List<City> getCityList(@PathVariable String provinceId) { return areaService.getCityListByProvinceId(provinceId); } @GetMapping("/areas/{cityId}") public List<Area> getAreaList(@PathVariable String cityId) { return areaService.getAreaListByCityId(cityId); } } ``` 以上就是实现Java后端省市三级级联的基本步骤。当用户选择省份时,通过AJAX请求获取城市数据,当用户选择城市时,再次通过AJAX请求获取区数据。最终,将三级数据进行组合,返回给用户。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值