Java多级菜单排序并返回树结构菜单列表方式

 更新时间:2026年06月15日 09:57:55   作者:TheTsing  
本文详细介绍了使用SpringBoot和MybatisPlus对数据库中的菜单进行排序,并以树形结构返回Json菜单列表的方法,涵盖数据库表结构设计、Java实体类定义及Service层实现等内容

前言

SpringBoot+MybatisPlus 对数据表中的菜单进行排序并返回树形Json格式的菜单列表

一、数据表

  • 菜单表:t_menu
  • 字段说明:name:菜单名称; status:1表示启用,表示停用; level:菜单级别说明; parent_id:父级菜单id,0表示一级菜单; sort_order:排序序号

二、Java实体

@Getter
@Setter
@Accessors(chain = true)
@TableName("t_menu")
public class Menu implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id")
    private String id; //菜单ID

    @JSONField(ordinal = 1)
    private String name;//菜单名称

    @JSONField(ordinal = 2)
    private Boolean status; //菜单状态 0表示禁用 1表示启用

    @JSONField(ordinal = 3)
    private String level;    //菜单级别 例如:一级菜单、二级菜单

    @JSONField(ordinal = 4)
    private String parentId; //父级ID 一级菜单

    @JSONField(ordinal = 5)
    private Integer sortOrder; //排序 0表示最前面

    //存放子菜单目录
    @JSONField(ordinal = 6)
    @TableField(exist = false)
    private List<Menu> children;

}

三、Service层

@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {

    @Override
    public List<Menu> getMenu() {
        List<Menu> allMenu = baseMapper.selectList(null);//查出全部菜单
        return allMenu.stream()
                .filter(item -> Objects.equals(item.getParentId(), "0"))
                .map(item -> item.setChildren(getChild(item.getId(), allMenu)))
                .sorted(Comparator.comparingInt(menu -> (menu.getSortOrder() == null ? 0 : menu.getSortOrder())))
                .collect(Collectors.toList());
    }

    private List<Menu> getChild(String id, List<Menu> allMenu) {
        return allMenu.stream()
                .filter(item -> Objects.equals(item.getParentId(), id))
                .map(item -> item.setChildren(getChild(item.getId(), allMenu)))
                .sorted(Comparator.comparingInt(menu -> (menu.getSortOrder() == null ? 0 : menu.getSortOrder())))
                .collect(Collectors.toList());
    }

}

四、结果

{
  "code": 2000,
  "data": [
    {
      "id": "1402904218656530433",
      "name": "位置管理",
      "status": true,
      "level": "一级菜单",
      "parentId": "0",
      "sortOrder": 0,
      "children": []
    },
    {
      "id": "1402904118723043329",
      "name": "日志管理",
      "status": true,
      "level": "一级菜单",
      "parentId": "0",
      "sortOrder": 5,
      "children": [
        {
          "id": "1402905060906328066",
          "name": "查看日志",
          "status": true,
          "level": "二级菜单",
          "parentId": "1402904118723043329",
          "sortOrder": 0,
          "children": []
        }
      ]
    },
    {
      "id": "1402903753264885762",
      "name": "用户管理",
      "status": true,
      "level": "一级菜单",
      "parentId": "0",
      "sortOrder": 7,
      "children": [
        {
          "id": "1402904547628376065",
          "name": "账号管理",
          "status": true,
          "level": "二级菜单",
          "parentId": "1402903753264885762",
          "sortOrder": 5,
          "children": []
        },
        {
          "id": "1402904663936425985",
          "name": "权限管理",
          "status": true,
          "level": "二级菜单",
          "parentId": "1402903753264885762",
          "sortOrder": 12,
          "children": [
            {
              "id": "1402904949253955585",
              "name": "修改权限",
              "status": true,
              "level": "三级菜单",
              "parentId": "1402904663936425985",
              "sortOrder": 2,
              "children": []
            },
            {
              "id": "1402904920229371906",
              "name": "添加权限",
              "status": true,
              "level": "三级菜单",
              "parentId": "1402904663936425985",
              "sortOrder": 10,
              "children": [
                {
                  "id": "1402922502042918914",
                  "name": "测试一",
                  "status": true,
                  "level": "四级菜单",
                  "parentId": "1402904920229371906",
                  "sortOrder": 0,
                  "children": []
                },
                {
                  "id": "1402922463040086018",
                  "name": "测试二",
                  "status": true,
                  "level": "四级菜单",
                  "parentId": "1402904920229371906",
                  "sortOrder": 4,
                  "children": []
                }
              ]
            },
            {
              "id": "1402904973903880194",
              "name": "删除权限",
              "status": true,
              "level": "三级菜单",
              "parentId": "1402904663936425985",
              "sortOrder": 10,
              "children": []
            }
          ]
        },
        {
          "id": "1402904645955444738",
          "name": "角色管理",
          "status": true,
          "level": "二级菜单",
          "parentId": "1402903753264885762",
          "sortOrder": 14,
          "children": []
        },
        {
          "id": "1402904723365519361",
          "name": "菜单管理",
          "status": true,
          "level": "二级菜单",
          "parentId": "1402903753264885762",
          "sortOrder": 30,
          "children": []
        }
      ]
    }
  ],
  "date": 1623480149457,
  "msg": "success",
  "success": true
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java中获取当前服务器的Ip地址的方法

    java中获取当前服务器的Ip地址的方法

    本篇文章主要介绍了java中获取当前服务器的Ip地址的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • Java项目中classpath类路径是什么

    Java项目中classpath类路径是什么

    classpath指的是类路径,也就是编译之后的target文件夹下的WEB-INF/class文件夹,下面这篇文章主要给大家介绍了关于Java项目中classpath类路径是什么的相关资料,需要的朋友可以参考下
    2023-02-02
  • java中删除文件/文件夹的3种方法示例小结

    java中删除文件/文件夹的3种方法示例小结

    这篇文章主要介绍了java中删除文件/文件夹的3种方法示例小结,第一种是通过io删除文件,第二种是通过Files.walk删除文件,第三种是通过 Files.walkFileTree删除文件,本文结合示例代码给大家介绍的非常详细,需要的朋友参考下吧
    2023-10-10
  • Java中的volatile关键字解析

    Java中的volatile关键字解析

    这篇文章主要介绍了Java中的volatile关键字解析,Java内存模型规定了所有的变量都存储在主内存中,每个线程都有自己的工作内存,线程的工作内存保存了该线程使用到的变量的是主内存副本的拷贝,需要的朋友可以参考下
    2023-11-11
  • 详解Java编程中面向字符的输出流

    详解Java编程中面向字符的输出流

    这篇文章主要介绍了Java编程中面向字符的输出流,是Java入门学习中的基础知识,需要的朋友可以参考下
    2015-10-10
  • Java编写时间工具类ZTDateTimeUtil的示例代码

    Java编写时间工具类ZTDateTimeUtil的示例代码

    这篇文章主要为大家详细介绍了如何利用Java编写时间工具类ZTDateTimeUtil,文中的示例代码讲解详细,有需要的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • Java Timer单线程下的定时任务举例详解

    Java Timer单线程下的定时任务举例详解

    在日常的项目开发中,多多少少都会涉及到一些定时任务的需求,下面这篇文章主要介绍了Java Timer单线程下定时任务的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-10-10
  • 一篇文章带你入门Java字面量和常量

    一篇文章带你入门Java字面量和常量

    这篇文章主要介绍了探究Java的常量,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08
  • Java使用BigDecimal确保数值计算精度的最佳实践指南

    Java使用BigDecimal确保数值计算精度的最佳实践指南

    这篇文章主要为大家详细介绍了Java使用BigDecimal确保数值计算精度的相关知识,BigDecimal一般适用于金融计算、高精度运算等对数值准确性要求高的场景,下面小编就和大家详细介绍一下吧
    2026-01-01
  • java并发编程专题(一)----线程基础知识

    java并发编程专题(一)----线程基础知识

    这篇文章主要介绍了java并发编程线程的基础知识,文中讲解非常详细,帮助大家更好的学习JAVA并发编程,感兴趣想学习JAVA的可以了解下
    2020-06-06

最新评论