MySQL樹形結構表設計

兩個字段:

  • pid:父級ID
  • parent_ids:所有經過的路徑節點ID

這樣設計有個好處是,可以查任意節點的所有子節點,從任意節點開始既可以向上查,也可以向下查

select * from enterprise where find_in_set(4, parent_ids); 

構造菜單樹(Java實現)

@Data
@NoArgsConstructor
public class Menu {
    private Integer id;
    private Integer pid;    //  父菜單ID
    private String pids;    //  所有父菜單ID集合(按順序,逗號分隔)
    private String name;
    private String code;
    private int sort;
    List<Menu> children;

    public Menu(Integer id, Integer pid, String name, int sort) {
        this.id = id;
        this.pid = pid;
        this.name = name;
        this.sort = sort;
    }
}

第一種寫法

@Test
void contextLoads() throws Exception {
    List<Menu> allMenuList = new ArrayList<>();
    allMenuList.add(new Menu(1, 0, "一級菜單A", 1));
    allMenuList.add(new Menu(2, 0, "一級菜單B", 2));
    allMenuList.add(new Menu(3, 1, "二級菜單AA", 1));
    allMenuList.add(new Menu(4, 2, "二級菜單BB", 1));
    allMenuList.add(new Menu(5, 3, "三級菜單AAA", 2));
    allMenuList.add(new Menu(6, 4, "三級菜單BBB", 2));
    allMenuList.add(new Menu(7, 1, "二級菜單AC", 2));
    
    //  找到所有一級菜單
    List<Menu> parentList = allMenuList.stream().filter(e->e.getPid().equals(0)).collect(Collectors.toList());
    for (Menu menu : parentList) {
        menu.setChildren(getChild(menu.getId(), allMenuList));
    }
}

/**
 * 遞歸查找子菜單
 */
public List<Menu> getChild(Integer pid, List<Menu> allMenuList) {
    List<Menu> childList = new ArrayList<>();
    for (Menu menu : allMenuList) {
        if (pid.equals(menu.getPid())) {
            menu.setChildren(getChild(menu.getId(), allMenuList));
            childList.add(menu);
        }
    }
    childList.sort(Comparator.comparing(Menu::getSort).reversed());
    return childList;
}

第二種寫法

@Test
void contextLoads() throws Exception {
    List<Menu> allMenuList = new ArrayList<>();
    allMenuList.add(new Menu(1, 0, "一級菜單A", 1));
    allMenuList.add(new Menu(2, 0, "一級菜單B", 2));
    allMenuList.add(new Menu(3, 1, "二級菜單AA", 1));
    allMenuList.add(new Menu(4, 2, "二級菜單BB", 1));
    allMenuList.add(new Menu(5, 3, "三級菜單AAA", 2));
    allMenuList.add(new Menu(6, 4, "三級菜單BBB", 2));
    allMenuList.add(new Menu(7, 1, "二級菜單AC", 2));

    //  第二種寫法
    List<Menu> list = allMenuList.stream()
            .filter(e->e.getPid().equals(0))
            .peek(e->e.setChildren(getChild2(e.getId(), allMenuList)))
            .sorted(Comparator.comparing(Menu::getSort))
            .collect(Collectors.toList());
}

/**
 * 遞歸查找子菜單(簡寫版)
 */
public List<Menu> getChild2(Integer pid, List<Menu> allMenuList) {
    return allMenuList.stream()
            .filter(e->pid.equals(e.getPid()))
            .peek(e->e.setChildren(getChild2(e.getId(), allMenuList)))
            .sorted(Comparator.comparing(Menu::getSort))
            .collect(Collectors.toList());
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章