递归加载菜单树

百科知识2025-04-261

1.创建数据库表

create table system_resource
(
id
bigint(11) not null primary key auto_increment comment id,
resource_name
varchar(20) not null comment 资源名称,
resource_name_cn
varchar(20) not null comment 资源中文名,
resource_parent_name
varchar(20) null comment 父级资源名称,
resource_url
varchar(100) null comment 资源路径,
resource_icon
varchar(100) comment 资源图标,
create_time
timestamp not null default 0000-00-00 00:00:00 comment 创建时间,
update_time
timestamp not null default current_timestamp on update current_timestamp comment 修改时间
) charset
= utf8mb4 comment 角色资源表;
create trigger resource_insert
before
insert
on system_resource
for each row set new.create_time = now();

插入测试数据:

 

 然后java代码加载菜单树:

新建一个菜单的bean对象,用来存放加载出来的菜单:

package com.whx.gxrsms.bean;

import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.List;

/**

  • /span><span>@author</span ZhaoShuai
  • @company lihfinance.com
  • @date Create in 2020/3/3
    /
    @Data
    @Accessors(chain
    = true)
    public class MenuTree implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    private String name;

    private String title;

    private String icon;

    private String href;

    private List list;
    }

    使用mybatis和通用mapper来写dao层,这一块就不写出来了,直接写主要方法:

    @Override
    public List getMenuTree() {
    /加载出所有的菜单/
    List
    resources = resourceMapper.select(new SystemResource());
    /筛选出所有的第一级菜单/
    List
    menuTrees = resources.parallelStream().filter(r -> StringUtils.isEmpty(r.getResourceParentName()))
    .map(
    this::convertResource)
    .collect(Collectors.toList());
    /加载出所有的子菜单/
    List
    childResource = resources.parallelStream()
    .filter(f
    -> !StringUtils.isEmpty(f.getResourceParentName()))
    .collect(Collectors.toList());
    /生成菜单树/
    menuTrees
    = menuTrees.parallelStream().map(m -> recursiveMenu(m, childResource)).collect(Collectors.toList());

    </span><span>return</span><span> menuTrees;

    }
    /**

    • @company lihfinance.com
    • /span><span>@author</span create by ZhaoShuai in 2020/3/3
    • 递归生成菜单树
    • /span><span>@param</span menuTree, resources
    • /span><span>@return</span com.whx.gxrsms.bean.MenuTree
      /
      private MenuTree recursiveMenu(MenuTree menuTree, List resources) {
      List
      childMenu = resources.parallelStream()
      .filter(r
      -> menuTree.getName().equals(r.getResourceParentName()))
      .map(
      this::convertResource).collect(Collectors.toList());
      if (!childMenu.isEmpty()) {
      childMenu
      = childMenu.parallelStream().map(m -> recursiveMenu(m, resources)).collect(Collectors.toList());
      }
      menuTree.setList(childMenu);
      return menuTree;
      }

    /**

    • @company lihfinance.com
    • /span><span>@author</span create by ZhaoShuai in 2020/3/3
    • 将资源转换为菜单类
    • /span><span>@param</span
    • /span><span>@return</span
      /
      private MenuTree convertResource(SystemResource resource) {
      MenuTree tree
      = new MenuTree();
      tree.setId(resource.getId());
      tree.setName(resource.getResourceName());
      tree.setTitle(resource.getResourceNameCn());
      tree.setHref(resource.getResourceUrl());
      tree.setIcon(resource.getResourceIcon());
      return tree;
      }

      然后配置controller,访问调用该方法:

      @RequestMapping("/getMenuTree")
      @ResponseBody
      public Result getMenuTree() {
      Result result
      = Result.success();

      List menuTrees = loginService.getMenuTree();
      result.setData(menuTrees);
      return result;
      }

      页面展示结果为:

      {"code":200,"msg":"操作成功","data":[{"id":1,"name":"system.manager","title":"系统管理","icon":"aaa","href":null,"list":[{"id":2,"name":"save.resource","title":"添加资源","icon":"bbb","href":"/gxrsms/resource.html","list":[]},{"id":3,"name":"role.manager","title":"角色管理","icon":null,"href":null,"list":[{"id":5,"name":"role.add","title":"添加角色","icon":"","href":"/gxrsms/role/insert","list":[]}]},{"id":4,"name":"user.manager","title":"用户管理","icon":null,"href":null,"list":[{"id":6,"name":"user.add","title":"添加用户","icon":"","href":"/gxrsms/user/insert","list":[]}]}]},{"id":7,"name":"dept.manager","title":"部门管理","icon":"ccc","href":null,"list":[{"id":8,"name":"dept.add","title":"添加部门","icon":"","href":"/gxrsms/dept/insert","list":[]}]}]}

      这就是我们要加载的菜单树了,json格式化后可以清楚的看出层级结构。