前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java递归生成树形菜单_java递归无限层级树

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

作者头像
全栈程序员站长
发布2022-09-29 11:17:23
3.1K0
发布2022-09-29 11:17:23
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

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

一、 权限树的问题由来

  1. 在开发中难免遇到一个有多级菜单结构树,或者多级部门的结构树,亦或是省市区县的多级结构,数据结构类似如下的json数据:
代码语言:javascript
复制
[
{ 

"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数据库的基础数据
在这里插入图片描述
在这里插入图片描述
  1. java的实体类:
代码语言:javascript
复制
@Data
@NoArgsConstructor
public class Menu implements Serializable { 

private String  id;
private String name;
private String pid;
private List<Menu> menuChildren;
}
  1. java的dao层
代码语言:javascript
复制
@Mapper
public interface MenuDao { 

/** * 根据父类id查询子类菜单 * @param pid * @return */
List<Menu> selectByPid(Integer pid);
/** * 查询所有的菜单 * @return */
List<Menu> selectAll();
/** * 查询除了一级菜单以外的菜单 * @return */
List<Menu> selectAllNotBase();
}
  1. mapper文件
代码语言:javascript
复制
<?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层)
代码语言:javascript
复制
@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数据如下:

代码语言:javascript
复制
[
{ 

"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.cn/193334.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月15日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、 权限树的问题由来
  • 二、 解决方案
  • 实现步骤
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档