避免递归查询子部门问题的实现方案

引言:我们在开发项目的时候难免会遇到部门下面有子部门,菜单下面有菜单的情况,当我们需要查询的时候最容易想到的就是递归查询,但是递归查询不是最好的方案。

本次我们用可以使用 Java8 中的 Stream 流一次性把数据查出来,然后通过流式处理。

实体类:Menu.java

@Data
public class Menu {
  private Integer id;

  private String name;

  private Integer parentId;

  private List<Menu> childList;

  public Menu(Integer id, String name, Integer parentId) {
    this.id = id;
    this.name = name;
    this.parentId = parentId;
  }

  public Menu(Integer id, String name, Integer parentId, List<Menu> childList) {
    this.id = id;
    this.name = name;
    this.parentId = parentId;
    this.childList = childList;
  }
}

模拟从数据库中查询出来的数据并递归组装树形结构

public void getTree(){
    // 模拟从数据库查询出来
    List<Menu> menus = Arrays.asList(
        new Menu(1, "根节点", 0),
        new Menu(2, "子节点1", 1),
        new Menu(3, "子节点1.1", 2),
        new Menu(4, "子节点1.2", 2),
        new Menu(5, "根节点1.3", 2),
        new Menu(6, "根节点2", 1),
        new Menu(7, "根节点2.2", 6),
        new Menu(8, "根节点2.2", 6),
        new Menu(9, "根节点2.2.1", 7),
        new Menu(10, "根节点2.2.2", 7),
        new Menu(13, "根节点2.2.2.1", 10),
        new Menu(11, "根节点3", 1),
        new Menu(12, "根节点3.1", 11)
    );

    // 获取父节点
    List<Menu> collect = menus.stream()
        .filter(m -> m.getParentId() == 0)
        .map(m -> {
            m.setChildList(getChildrens(m, menus));
            return m;
        }).collect(Collectors.toList());

    System.out.println("--------转 json 输出结果 ----------");
    System.out.println(JSONUtil.toJsonStr(collect));
}

// 设置内菜单数据
private List<Menu> getChildrens(Menu root,List<Menu> all) {
    return all.stream()
        .filter(m -> Objects.equals(m.getParentId(), root.getId())).map(m -> {
        m.setChildList(getChildrens(m, all));
        return m;
    }).collect(Collectors.toList());
}

运行结果

[{
	"childList": [{
		"childList": [{
			"childList": [],
			"parentId": 2,
			"name": "子节点1.1",
			"id": 3
		}, {
			"childList": [],
			"parentId": 2,
			"name": "子节点1.2",
			"id": 4
		}, {
			"childList": [],
			"parentId": 2,
			"name": "根节点1.3",
			"id": 5
		}],
		"parentId": 1,
		"name": "子节点1",
		"id": 2
	}, {
		"childList": [{
			"childList": [{
				"childList": [],
				"parentId": 7,
				"name": "根节点2.2.1",
				"id": 9
			}, {
				"childList": [{
					"childList": [],
					"parentId": 10,
					"name": "根节点2.2.2.1",
					"id": 13
				}],
				"parentId": 7,
				"name": "根节点2.2.2",
				"id": 10
			}],
			"parentId": 6,
			"name": "根节点2.2",
			"id": 7
		}, {
			"childList": [],
			"parentId": 6,
			"name": "根节点2.2",
			"id": 8
		}],
		"parentId": 1,
		"name": "根节点2",
		"id": 6
	}, {
		"childList": [{
			"childList": [],
			"parentId": 11,
			"name": "根节点3.1",
			"id": 12
		}],
		"parentId": 1,
		"name": "根节点3",
		"id": 11
	}],
	"parentId": 0,
	"name": "根节点",
	"id": 1
}]

使用流的方式可以减少了我们与数据库之间的交互,希望读者有一定帮助。

你可能感兴趣的:(Stream流)