java递归生成树形菜单_java递归无限层级树

java递归生成树形菜单_java递归无限层级树java递归实现权限树(菜单树)省市县多级结构

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

完整示例代码地址如下:
https://github.com/Dr-Water/springboot-action/tree/master/springboot-shiro

一、 权限树的问题由来

  1. 在开发中难免遇到一个有多级菜单结构树,或者多级部门的结构树,亦或是省市区县的多级结构,数据结构类似如下的json数据:
[
    { 
   
        "id": "1",
        "name": "主菜单1",
        "pid": "0",
        "menuChildren": [
            { 
   
                "id": "4",
                "name": "子菜单1.1",
                "pid": "1",
                "menuChildren": [
                    { 
   
                        "id": "6",
                        "name": "子菜单1.1.1",
                        "pid": "4",
                        "menuChildren": []
                    },
                    { 
   
                        "id": "9",
                        "name": "子菜单1.1.2",
                        "pid": "4",
                        "menuChildren": []
                    }
                ]
            },
            { 
   
                "id": "5",
                "name": "子菜单1.2",
                "pid": "1",
                "menuChildren": []
            }
        ]
    },
    { 
   
        "id": "2",
        "name": "主菜单2",
        "pid": "0",
        "menuChildren": [
            { 
   
                "id": "7",
                "name": "子菜单2.1",
                "pid": "2",
                "menuChildren": []
            },
            { 
   
                "id": "8",
                "name": "子菜单2.2",
                "pid": "2",
                "menuChildren": []
            }
        ]
    },
    { 
   
        "id": "3",
        "name": "主菜单3",
        "pid": "0",
        "menuChildren": []
    }
]

二、 解决方案

目前的解决方案主要有以下两种方案:

  • 方案一:后端把所有需要的数据以一个大list返回前端,前端进行操作,把数据搞成树状结构
  • 方案二: 后端在后端返回数据之前把数据搞成已经有层次结构的数据,方案二也分为两种解决方法
    • 方法一:次性将数据查询出来,在java程序中进行树状结构的构建
    • 方法二: 第一次将最高层次的数据查询出来,然后多次循环查询数据库将子数据查询出来

由于博主的前端水平有限,目前只能用后端的实现方式,再加上每次查询数据库的开销比较大,所以本文使用方案二的方法一进行验证

实现步骤

以菜单的结构树为例

  1. 准备mysql数据库的基础数据
    在这里插入图片描述
  2. java的实体类:
@Data
@NoArgsConstructor
public class Menu implements Serializable { 
   

    private String  id;
    private String name;
    private String pid;
    private List<Menu> menuChildren;
}
  1. java的dao层
@Mapper
public interface MenuDao { 
   

    /** * 根据父类id查询子类菜单 * @param pid * @return */
     List<Menu> selectByPid(Integer pid);

    /** * 查询所有的菜单 * @return */
     List<Menu> selectAll();

    /** * 查询除了一级菜单以外的菜单 * @return */
     List<Menu> selectAllNotBase();
}
  1. mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ratel.shiro.dao.MenuDao">


    <select id="selectByPid" resultType="com.ratel.shiro.entity.Menu">
        SELECT * FROM menu WHERE  pid=#{pid}
    </select>

    <select id="selectAll" resultType="com.ratel.shiro.entity.Menu">
        SELECT * FROM menu
    </select>

    <select id="selectAllNotBase" resultType="com.ratel.shiro.entity.Menu">
        SELECT * FROM menu where pid!= 0
    </select>
</mapper>
  1. Controller层(由于是查询操作,并且没有复杂的操作,偷个懒就不写service层)
@RestController
@RequestMapping("mymenu")
public class MenuController { 
   

    @Autowired
    private MenuDao menuDao;


    @RequestMapping("/getMenuTree")
    public List<Menu> getMenuTree(){ 
   
        List<Menu> menusBase = menuDao.selectByPid(0);
        List<Menu> menuLNotBase = menuDao.selectAllNotBase();
        for (Menu menu : menusBase) { 
   
            List<Menu> menus = iterateMenus(menuLNotBase, menu.getId());
            menu.setMenuChildren(menus);
        }
        return  menusBase;
    }


    /** *多级菜单查询方法 * @param menuVoList 不包含最高层次菜单的菜单集合 * @param pid 父类id * @return */
    public List<Menu> iterateMenus(List<Menu> menuVoList,String pid){ 
   
        List<Menu> result = new ArrayList<Menu>();
        for (Menu menu : menuVoList) { 
   
            //获取菜单的id
            String menuid = menu.getId();
            //获取菜单的父id
            String parentid = menu.getPid();
            if(StringUtils.isNotBlank(parentid)){ 
   
                if(parentid.equals(pid)){ 
   
                    //递归查询当前子菜单的子菜单
                    List<Menu> iterateMenu = iterateMenus(menuVoList,menuid);
                    menu.setMenuChildren(iterateMenu);
                    result.add(menu);
                }
            }
        }
        return result;
    }
}
  1. 启动程序用postman进行测试:
    在这里插入图片描述
    返回的json数据如下:
[
    { 
   
        "id": "1",
        "name": "主菜单1",
        "pid": "0",
        "menuChildren": [
            { 
   
                "id": "4",
                "name": "子菜单1.1",
                "pid": "1",
                "menuChildren": [
                    { 
   
                        "id": "6",
                        "name": "子菜单1.1.1",
                        "pid": "4",
                        "menuChildren": []
                    },
                    { 
   
                        "id": "9",
                        "name": "子菜单1.1.2",
                        "pid": "4",
                        "menuChildren": []
                    }
                ]
            },
            { 
   
                "id": "5",
                "name": "子菜单1.2",
                "pid": "1",
                "menuChildren": []
            }
        ]
    },
    { 
   
        "id": "2",
        "name": "主菜单2",
        "pid": "0",
        "menuChildren": [
            { 
   
                "id": "7",
                "name": "子菜单2.1",
                "pid": "2",
                "menuChildren": []
            },
            { 
   
                "id": "8",
                "name": "子菜单2.2",
                "pid": "2",
                "menuChildren": []
            }
        ]
    },
    { 
   
        "id": "3",
        "name": "主菜单3",
        "pid": "0",
        "menuChildren": []
    }
]

参考链接:
java递归 处理权限管理菜单树或分类
一次性搞定权限树遍历——–权限树后台遍历的通用解决方案
(java后台)用户权限的多级菜单遍历方法
java 用递归实现球上下级(牵涉到对上级的去重)
java递归获取某个父节点下面的所有子节点
java递归算法总结

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/193334.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java最简单最全入门基础笔记(不简单,不全你打我)「建议收藏」

    java最简单最全入门基础笔记(不简单,不全你打我)「建议收藏」刚开始学习java的时候,可能是一头雾水,不知道从何学起,这里跟大家分享一下!(仅仅只供初级学者学习,大佬勿喷)一、初始java1.生活中的程序:从起床到教室上课的过程穿衣打扮》起床》洗漱》出宿舍》》吃早餐》到教室按照特定的顺序去完成某一件事的过程我们叫做生活中的程序2.计算机中的程序:一组有序指令的集合,需要和计算机交流就要使用计算机语言,java就是计算机语言的一种3.java…

    2022年6月4日
    32
  • 51单片机之逻辑运算指令ANL、ORL、XRL等

    51单片机之逻辑运算指令ANL、ORL、XRL等文章目录前言一、简单操作指令CLR、CPL、SWAPCLRACPLASWAPA二、位移指令RL、RR、RLC、RRCRLARRARLCARRCA三、逻辑“与”指令ANLANLA,XXXANLdirect,XXX四、逻辑“或”指令ORLORLA,XXXORLdirect,XXX五、逻辑“异或”指令XRLORLA,XXXXRLdirect,XXX前言…

    2022年7月26日
    21
  • rviz的简单使用[通俗易懂]

    rviz的简单使用[通俗易懂]原链接:http://community.bwbot.orgrviz是ros自带的一个图形化工具,可以方便的对ros的程序进行图形化操作。其使用也是比较简单。整体界面如下图所示界面主要分为左侧的显示设置区域,中间的大的显示区域和右侧的视角设置区域。最上面是和导航相关的几个工具。最下面是ros状态相关的一些数据的显示。下面以用rviz查看ORB_SLAM2的topic数据为例展示一下rvi

    2022年4月20日
    144
  • 配置gitignore后使其生效命令

    配置gitignore后使其生效命令

    2021年10月20日
    44
  • 软件测试全套教程,软件测试自学线路图

    软件测试全套教程,软件测试自学线路图软件测试:软件测试是为了发现程序中的错误而执行程序的过程。通俗的说,软件测试需要在发布软件之前,尽可能的找软件的错误,尽量避免在发布之后给用户带来不好的体验,并要满足用户使用的需求。现在市面上这么多软件,每个软件背后都有软件测试工程师的功劳,这也造就了软件测试行业前景非常好,今天我就分享一下自学线路图,及全套教程!软件测试学习线路图点击查看大图第一阶段:该…

    2022年6月11日
    41
  • MyBatis+SpringBoot整合 注入SqlSessionTemplate

    MyBatis+SpringBoot整合 注入SqlSessionTemplate实际开发中我们操作数据库持久化,总是需要写重复的mapper,service,xml浪费了我们大量的时间,在这里推荐大家使用SqlSessionTemplate废话不多说直接上代码工具类接口层:packagecom.miaosuan.dao;importjava.util.List;importcom.miaosuan.dao.dbenums.NameSpaceEnum;…

    2022年5月6日
    58

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号