实体类,含parentId,这个的 List
children上面加 @TableField(exist = false)注解是由于表中没有此字段。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Menu {
Long id;
Long parentId;
String name;
String url;
String perms ;
Integer type ;
String icon ;
Integer orderNum ;
String createBy ;
String createTime ;
String lastUpdateBy ;
String lastUpdateTime ;
Integer delFlag ;
String parentName ;
Integer level ;
@TableField(exist = false)
List<Menu> children;
}
业务逻辑
@Override
public List<Menu> findMenuTree() {
//拿到总资源
List<Menu> tree = menuMapper.findMenuTree();
// 最后要返回的结果
List<Menu> newMenuList = new ArrayList<>();
// 先找到所有的一级菜单
for (int i = 0; i < tree.size(); i++){
Menu menu=tree.get(i);
Long parentId=menu.getParentId();
// 如果是顶级菜单,没有父菜单,直接放入返回结果集
if (parentId==0){
newMenuList.add(menu);
}
}
// 为菜单设置子菜单,getChild是递归调用的,若子菜单有子菜单则一直递归,直到子菜单的children为空
for (Menu menu : newMenuList) {
menu.setChildren(getChild(menu.getId(), tree));
}
return newMenuList;
}
递归调用的方法
// 递归查找子菜单
private List<Menu> getChild(long id, List<Menu> rootMenu) {
// 子菜单集合
List<Menu> childList = new ArrayList<>();
for (Menu menu : rootMenu) {
// 遍历所有节点,将父菜单id与传过来的id比较
if (menu.getParentId()==id) {
childList.add(menu);
}
}
// 把子菜单的子菜单再循环一遍
for (Menu menu : childList) {
// 递归
menu.setChildren(getChild(menu.getId(), rootMenu));
} // 递归退出条件
if (childList.size() == 0) {
return null;
}
return childList;
}
一开始自己的想法是用表的自联结查出然后塞进Children中,但是@进击的小王666https://blog.csdn.net/m0_56033865?spm=1001.2014.3001.5512的想法更简单