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

导读:本篇文章讲解 java8新特性 非常简单的递归查询所有子节点树,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

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

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

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

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

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

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

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

二、 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<MenuVO> children;

}

3、service实现 重点来了:

    @Override
    public List<MenuVO> getListMenuVO(List<Integer> roleId) {
        //查询出所有菜单,这里过滤了一个状态条件(mybatis-puls的写法,不了解的同学可以去看下mybatis-puls)
        QueryWrapper<SysMenu> sysMenuQueryWrapper = new QueryWrapper<>();
        sysMenuQueryWrapper.eq("status",1);
        sysMenuQueryWrapper.orderByAsc("sort");
        List<SysMenu> sysMenus = list(sysMenuQueryWrapper);
        //第一个参数必须是当前最高目录的parentId的值,这里写0也就是一级目录的parentId的值
        return recursionForMenu(0,sysMenus);
    }
    /**
     * 左侧菜单通过递归算法实现树
     * @param parentId 父Id
     * @param menuList 当前所有菜单
     * @return
     */
    private List<MenuVO> recursionForMenu(int parentId,List<SysMenu> menuList){
        List<MenuVO> 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<MenuVO> 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<ResponseInfo> getMenuList(HttpServletRequest request) {
        ResponseInfo ri = new ResponseInfo();
        List<MenuVO> 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": []
                }
            ]
        }
    ]

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/67236.html

(2)
小半的头像小半

相关推荐

半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!