java生成多级菜单树

使用java实现一个多级菜单树结构

先上数据库

ps_pid字段很重要,是父级菜单的id

Menu类要新增一个字段,用来存放子菜单

    /**
     * 子菜单列表
     */
    private List<Menu> children;

用mybatis实现

生成菜单树第一种方式可以利用mybatiscollection查询实现

<collection property="children" ofType="com.example.springbootvue.entity.Menu"
 column="ps_id" select="findMenuByParentId"/>

column="ps_id"表示传到findMenuByParentId这个方法中去的参数,是父ID
mybatis会再进行一次查询,把ps_pid=ps_idMenu回添到children列表中,自动递归
不过这样会导致mybatis N+1问题 官方建议不使用这种写法

使用java算法实现

最开始获取全部菜单我使用的mybatis实现生成菜单树,后来写用户权限管理模块的时候,用户的权限不再是所有菜单,而是部分菜单,使用mybatis还没想到解决办法,手动狗头,
然后看了一个大佬写的java生成树代码,真的太妙了,先把获取全部菜单,然后再对菜单进行装配,生成树形结构,话不多说,上代码

//获取菜单树
  public List<Menu> getMenuList() {
    //获取所有菜单
    List<Menu> menuList = menuMapper.getMenuList();
   //返回的菜单树列表
    List<Menu> menuTree = new ArrayList<>();
    //  先找到所有的一级菜单,放入菜单树列表中
    for (Menu menu : menuList) {
      if (menu.getPsLevel().equals("0")) {
        menuTree.add(menu);
      }
    }
    //遍历一级菜单,开始查找子菜单
    for (Menu menu : menuTree) {
      menu.setChildren(getChildren(menu.getPsId(),menuList));
    }
    return menuList;
  }

  private List<Menu> getChildren(Short psId, List<Menu> menuList) {
    //  查找二级子菜单
    List<Menu> childList = new ArrayList<>();
    for (Menu menu : menuList) {
      if (menu.getPsPid().equals(psId)) {
        childList.add(menu);
      }
    }
    //递归查找查找二级菜单的子菜单
    for (Menu menu : childList) {
      menu.setChildren(getChildren(menu.getPsId(),menuList));
    }
    return childList;
  }

这样会导致很多重复操作,如果使用java的stream进行过滤性能会更好,等有时间了再更一下

原文地址:https://www.cnblogs.com/Fzeng/p/14812934.html