java8新特性 非常简单的递归查询所有子节点树

在开发中很多同学都遇到过遍历 查询所有子节点的业务,在这里给大家分析 使用java8的语法 很简单的递归来实现

我就拿一个最普遍的 菜单遍历案例分享给大家

一、首先看看我的菜单表结构

java8新特性 非常简单的递归查询所有子节点树_第1张图片

其中我添加了一点数据来测试

 可以看到我所有菜单的父级都是 系统管理(自己也可以添加不同的父子级关系)

二、 Java8递归遍历

1、菜单的实体类

@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="SysMenu对象", description="")
public class SysMenu implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "ID")
    @TableId(value = "menu_id", type = IdType.AUTO)
    private Integer menuId;

    @ApiModelProperty(value = "父ID")
    private Integer parentId;

    @ApiModelProperty(value = "名称")
    private String name;

    @ApiModelProperty(value = "路径")
    private String component;

    @ApiModelProperty(value = "路由")
    private String path;

    @ApiModelProperty(value = "等级")
    private Integer level;

    @ApiModelProperty(value = "类型   0:目录,1:菜单, 2:按钮")
    private Integer type;

    @ApiModelProperty(value = "图标")
    private String icon;

    @ApiModelProperty(value = "排序")
    private Integer sort;

    @ApiModelProperty(value = "状态   0:失效   1:启用")
    private Integer status;

    @ApiModelProperty(value = "shiro权限标识")
    private String permit;

    @ApiModelProperty(value = "父名称")
    @TableField(exist = false)
    private String pname;

}

2、前端需要的树形格式  这里用VO(这里我前端是用的elment-ui的树)

/**
 * 菜单的VO
 */
@Data
public class MenuVO {
    private String path;
    private String component;
    private boolean alwaysShow;
    private String name;
    private MetaVO meta;
    private List children;

}

3、service实现 重点来了:

    @Override
    public List getListMenuVO(List roleId) {
        //查询出所有菜单,这里过滤了一个状态条件(mybatis-puls的写法,不了解的同学可以去看下mybatis-puls)
        QueryWrapper sysMenuQueryWrapper = new QueryWrapper<>();
        sysMenuQueryWrapper.eq("status",1);
        sysMenuQueryWrapper.orderByAsc("sort");
        List sysMenus = list(sysMenuQueryWrapper);
        //第一个参数必须是当前最高目录的parentId的值,这里写0也就是一级目录的parentId的值
        return recursionForMenu(0,sysMenus);
    }
    /**
     * 左侧菜单通过递归算法实现树
     * @param parentId 父Id
     * @param menuList 当前所有菜单
     * @return
     */
    private List recursionForMenu(int parentId,List menuList){
        List list = new ArrayList<>();
        /**
         * Optional.ofNullable(menuList).orElse(new ArrayList<>())  如果menuList是空的则返回一个new ArrayList<>()
         *  .stream() 返回List中的流
         *  .filter(menu -> menu.getParentId().equals(parentId)) 筛选List,返回只有条件成立的元素(当前元素的parentId必须等于父id)
         *  .forEach 遍历这个list
         */
        Optional.ofNullable(menuList).orElse(new ArrayList<>())
                .stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                .forEach(menu -> {
                    MenuVO menuVO = new MenuVO();
                    menuVO.setName(menu.getName());
                    //是否是目录
                    menuVO.setAlwaysShow(menu.getLevel().equals(1)?true:false);
                    menuVO.setPath(menu.getPath());
                    menuVO.setComponent(StringUtils.isNotEmpty(menu.getComponent())?menu.getComponent():"Layout");
                    menuVO.setMeta(new MetaVO(menu.getName(),menu.getIcon(),new ArrayList<>(Arrays.asList(1))));
                    List children=recursionForMenu(menu.getMenuId(),menuList);
                    menuVO.setChildren(children);
                    list.add(menuVO);
                });
        return list;
    }

如果有了解 stream、filter的同学应该很容易看懂,代码快上给大家写了简单的注释来解释了下

4、controller控制器

    @Autowired
    private SysMenuService sysMenuService;

    @ApiOperation(value = "获取菜单树")
    @GetMapping("/getMenuList")
    public ResponseEntity getMenuList(HttpServletRequest request) {
        ResponseInfo ri = new ResponseInfo();
        List menuVOS = sysMenuService.getListMenuVO(null);
        ri.setData(menuVOS);
        return ResponseEntity.ok().body(ri.ok());
    }

5、结果

"data": [
        {
            "path": "/permission",
            "component": "Layout",
            "alwaysShow": true,
            "name": "系统管理",
            "meta": {
                "title": "系统管理",
                "icon": "el-icon-s-tools",
                "roles": [
                    1
                ]
            },
            "children": [
                {
                    "path": "organization",
                    "component": "user/organization/organization-index",
                    "alwaysShow": false,
                    "name": "企业管理",
                    "meta": {
                        "title": "企业管理",
                        "icon": "el-icon-office-building",
                        "roles": [
                            1
                        ]
                    },
                    "children": []
                },
                {
                    "path": "page",
                    "component": "permission/directive",
                    "alwaysShow": false,
                    "name": "角色管理",
                    "meta": {
                        "title": "角色管理",
                        "icon": "el-icon-s-custom",
                        "roles": [
                            1
                        ]
                    },
                    "children": []
                },
                {
                    "path": "role",
                    "component": "permission/role",
                    "alwaysShow": false,
                    "name": "部门管理",
                    "meta": {
                        "title": "部门管理",
                        "icon": "el-icon-s-home",
                        "roles": [
                            1
                        ]
                    },
                    "children": []
                },
                {
                    "path": "menu",
                    "component": "user/menu/menu-index",
                    "alwaysShow": false,
                    "name": "菜单管理",
                    "meta": {
                        "title": "菜单管理",
                        "icon": "el-icon-s-order",
                        "roles": [
                            1
                        ]
                    },
                    "children": []
                }
            ]
        }
    ]

你可能感兴趣的:(树结构,vue.js,java,树结构)