java返回数据库中层级结构数据的纯算法写法,以动态菜单为例
说明
1.纯算法版本,跟treeListMap版本比起来的优点是,纯算法版只查询了一次数据库
2.里面有不同角色分配不同的菜单相关代码,注意复制粘贴。
3.可以无限嵌套层次结构,这里只用到了两层,仅为举例
先看效果
超级管理员结果展示
{
"code": 200,
"success": true,
"msg": "获取成功",
"sign": "",
"result": [
{
"id": "59664367-11eb-489e-867d-af6c66129d03",
"parentId": "0",
"level": 1,
"sort": 1,
"type": 2,
"path": "/Home/Introduce",
"title": "首页",
"icon": "home",
"children": []
},
{
"id": "30633357-dd12-415e-8631-660e2aa6b9ad",
"parentId": "",
"level": 1,
"sort": 2,
"type": 2,
"path": null,
"title": "信息管理",
"icon": "home",
"children": [
{
"id": "e50cadbc-8b2b-4c8f-a262-9da95d3371bb",
"parentId": "30633357-dd12-415e-8631-660e2aa6b9ad",
"level": 2,
"sort": 1,
"type": 2,
"path": "/InfoManage/SoftManage/List",
"title": "软件管理",
"icon": "",
"children": null
},
{
"id": "94beb8ae-a606-4dea-bfa8-57bc734818bf",
"parentId": "30633357-dd12-415e-8631-660e2aa6b9ad",
"level": 2,
"sort": 2,
"type": 2,
"path": "/InfoManage/VersionsManage/List",
"title": "版本管理",
"icon": "",
"children": null
},
{
"id": "bcb68a35-eb0f-4696-acd8-3c76897e0f0f",
"parentId": "30633357-dd12-415e-8631-660e2aa6b9ad",
"level": 2,
"sort": 3,
"type": 2,
"path": "/InfoManage/UserManage/List",
"title": "用户管理",
"icon": "",
"children": null
}
]
},
{
"id": "d6321208-4980-46e3-b3d4-ec057009472c",
"parentId": "0",
"level": 1,
"sort": 3,
"type": 1,
"path": null,
"title": "数据维护",
"icon": "home",
"children": [
{
"id": "b89eb2d8-40e4-4698-ab5a-ddaed7846ee1",
"parentId": "d6321208-4980-46e3-b3d4-ec057009472c",
"level": 2,
"sort": 1,
"type": 2,
"path": "/DataMaintenance/MsgManage/List",
"title": "回复管理",
"icon": null,
"children": null
},
{
"id": "e70b3176-a2fa-4fc5-90f3-5abd9e2d13b8",
"parentId": "d6321208-4980-46e3-b3d4-ec057009472c",
"level": 2,
"sort": 2,
"type": 2,
"path": "/DataMaintenance/CardPassManage/List",
"title": "卡密管理",
"icon": null,
"children": null
},
{
"id": "1d3838df-bc61-42e1-a149-dcc2705e2894",
"parentId": "d6321208-4980-46e3-b3d4-ec057009472c",
"level": 2,
"sort": 3,
"type": 2,
"path": "/DataMaintenance/FuncManage/List",
"title": "函数管理",
"icon": null,
"children": null
},
{
"id": "5b35fe6a-da5f-46d5-b1ed-076308a38a13",
"parentId": "d6321208-4980-46e3-b3d4-ec057009472c",
"level": 2,
"sort": 4,
"type": 2,
"path": "/DataMaintenance/EventManage/List",
"title": "事件管理",
"icon": null,
"children": null
},
{
"id": "a59b674e-8d45-46c2-be6e-ff44d2ee7b86",
"parentId": "d6321208-4980-46e3-b3d4-ec057009472c",
"level": 2,
"sort": 5,
"type": 2,
"path": "/DataMaintenance/BannedManage/List",
"title": "封禁管理",
"icon": null,
"children": null
},
{
"id": "dbe9effe-0dc8-4378-a64c-5bf904ac6fae",
"parentId": "d6321208-4980-46e3-b3d4-ec057009472c",
"level": 2,
"sort": 6,
"type": 2,
"path": "/DataMaintenance/DataManage/List",
"title": "数据管理",
"icon": null,
"children": null
}
]
},
{
"id": "43767678-01c5-4b54-bfac-e108b6ceb32a",
"parentId": "0",
"level": 1,
"sort": 4,
"type": 1,
"path": null,
"title": "系统管理",
"icon": "home",
"children": [
{
"id": "d7720078-3b65-4f83-b404-c117e5c46b68",
"parentId": "43767678-01c5-4b54-bfac-e108b6ceb32a",
"level": 2,
"sort": 1,
"type": 2,
"path": "/InfoManage/AdminManage/List",
"title": "管理员管理",
"icon": null,
"children": null
},
{
"id": "9d953050-f354-4e9f-9f15-b91ea6a666f0",
"parentId": "43767678-01c5-4b54-bfac-e108b6ceb32a",
"level": 2,
"sort": 2,
"type": 2,
"path": "/asd",
"title": "管理员日志",
"icon": null,
"children": null
},
{
"id": "71eedb8d-ae9e-4958-a351-c8dfb4711f21",
"parentId": "43767678-01c5-4b54-bfac-e108b6ceb32a",
"level": 2,
"sort": 3,
"type": 2,
"path": "/DataMaintenance/LogManage/List",
"title": "用户日志",
"icon": null,
"children": null
},
{
"id": "546ea73a-1d46-41f5-bfa6-e646b3e741ae",
"parentId": "43767678-01c5-4b54-bfac-e108b6ceb32a",
"level": 2,
"sort": 4,
"type": 2,
"path": "/asd",
"title": "菜单管理",
"icon": null,
"children": null
},
{
"id": "d58b4547-e20f-4eb9-b7d5-b3195ed5cc18",
"parentId": "43767678-01c5-4b54-bfac-e108b6ceb32a",
"level": 2,
"sort": 5,
"type": 2,
"path": "/asd",
"title": "角色管理",
"icon": null,
"children": null
},
{
"id": "014bf6d7-cff3-4b61-aa3b-f59cc0dd3235",
"parentId": "43767678-01c5-4b54-bfac-e108b6ceb32a",
"level": 2,
"sort": 6,
"type": 2,
"path": "/asd",
"title": "策略管理",
"icon": null,
"children": null
},
{
"id": "d27462d2-b316-4983-9066-f283fcf17e46",
"parentId": "43767678-01c5-4b54-bfac-e108b6ceb32a",
"level": 2,
"sort": 7,
"type": 2,
"path": "/asd",
"title": "系统管理",
"icon": null,
"children": null
}
]
},
{
"id": "da3af6df-cd00-4746-b788-bd2dfeab716f",
"parentId": "0",
"level": 1,
"sort": 5,
"type": 1,
"path": null,
"title": "我的管理",
"icon": "home",
"children": [
{
"id": "922666ba-1ed1-4b6b-9043-30aeead1eebe",
"parentId": "da3af6df-cd00-4746-b788-bd2dfeab716f",
"level": 2,
"sort": 1,
"type": 2,
"path": "/asd",
"title": "我的授权",
"icon": null,
"children": null
},
{
"id": "23a8778f-9424-449a-a68e-54b12e4c30f3",
"parentId": "da3af6df-cd00-4746-b788-bd2dfeab716f",
"level": 2,
"sort": 2,
"type": 2,
"path": "/asd",
"title": "我的卡密",
"icon": null,
"children": null
},
{
"id": "cd256048-3f8e-4fb7-ada3-55d538ce7611",
"parentId": "da3af6df-cd00-4746-b788-bd2dfeab716f",
"level": 2,
"sort": 3,
"type": 2,
"path": "/asd",
"title": "我的余额",
"icon": null,
"children": null
}
]
}
],
"timestamp": 1646991442708
}
代理结果展示
{
"code": 200,
"success": true,
"msg": "获取成功",
"sign": "",
"result": [
{
"id": "da3af6df-cd00-4746-b788-bd2dfeab716f",
"parentId": "0",
"level": 1,
"sort": 5,
"type": 1,
"path": null,
"title": "我的管理",
"icon": "home",
"children": [
{
"id": "922666ba-1ed1-4b6b-9043-30aeead1eebe",
"parentId": "da3af6df-cd00-4746-b788-bd2dfeab716f",
"level": 2,
"sort": 1,
"type": 2,
"path": "/asd",
"title": "我的授权",
"icon": null,
"children": null
},
{
"id": "23a8778f-9424-449a-a68e-54b12e4c30f3",
"parentId": "da3af6df-cd00-4746-b788-bd2dfeab716f",
"level": 2,
"sort": 2,
"type": 2,
"path": "/asd",
"title": "我的卡密",
"icon": null,
"children": null
},
{
"id": "cd256048-3f8e-4fb7-ada3-55d538ce7611",
"parentId": "da3af6df-cd00-4746-b788-bd2dfeab716f",
"level": 2,
"sort": 3,
"type": 2,
"path": "/asd",
"title": "我的余额",
"icon": null,
"children": null
}
]
}
],
"timestamp": 1646991115335
}
数据库
menu表结构

menu表数据

role表结构,仅为演示

role表数据,仅为演示
超级管理员分配了全部菜单权限
代理角色只分配了4个菜单权限
——我的管理
————我的授权
————我的卡密
————我的余额

实体类
menu
package cn.myauthx.api.main.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author DaenMax
* @since 2022-01-06
*/
@Data
@Accessors(chain = true)
@TableName("ma_menu")
public class Menu extends Model {
private static final long serialVersionUID = 1L;
private String id;
/**
* 父ID,根则空
*/
private String parentId;
/**
* 层级,从1开始
*/
private Integer level;
/**
* 排序,越小越大,从1开始
*/
private Integer sort;
/**
* 1=目录,2=菜单
*/
private Integer type;
private String path;
private String title;
private String icon;
@TableField(exist = false)
private List<Menu> children;
}
role
package cn.myauthx.api.main.entity;
import cn.myauthx.api.base.po.baseEntity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author DaenMax
* @since 2022-03-09
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("ma_role")
public class Role extends baseEntity {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 角色名
*/
private String name;
/**
* 0=超级管理员
*/
private Integer fromSoftId;
/**
* 只存menu的id,json数组
*/
private String meunIds;
/**
* 折扣,单位百分%
*/
private Integer discount;
}
算法
/**
* 获取权限菜单,算法版
*
* @param admin
* @return
*/
@Override
public Result getMenuList(Admin admin) {
List<Menu> tmpMenuList = new ArrayList<>();
Role role = roleMapper.selectById(admin.getRole());
if (CheckUtils.isObjectEmpty(role.getMeunIds())) {
return Result.error("没有任何菜单", tmpMenuList);
}
JSONArray jsonArray = JSONArray.parseArray(role.getMeunIds());
if (jsonArray.size() == 0) {
return Result.error("没有任何菜单", tmpMenuList);
}
LambdaQueryWrapper<Menu> menuLambdaQueryWrapper = new LambdaQueryWrapper<>();
menuLambdaQueryWrapper.in(Menu::getId, jsonArray);
menuLambdaQueryWrapper.orderBy(true, true, Menu::getLevel);
List<Menu> menuList = menuMapper.selectList(menuLambdaQueryWrapper);
if (menuList.size() == 0) {
return Result.error("没有任何菜单", tmpMenuList);
}
//最深的层次数
Integer maxLevel = menuList.get(menuList.size() - 1).getLevel();
//从最里层开始循环
for (Integer i = maxLevel; i > 0; i--) {
List<Menu> menuListByLevel = getMenuListByLevel(menuList, i);
if (i.equals(maxLevel)) {
tmpMenuList = menuListByLevel;
} else {
//外循环父节点
for (Menu menu : menuListByLevel) {
List<Menu> children = new ArrayList<>();
//内循环子节点
for (Menu tmpMenu : tmpMenuList) {
if (menu.getId().equals(tmpMenu.getParentId())) {
children.add(tmpMenu);
}
}
menu.setChildren(children);
}
tmpMenuList = menuListByLevel;
}
}
return Result.ok("获取成功", tmpMenuList);
}
/**
* 取指定level(层次)的数据
*
* @param list
* @param level
* @return
*/
public List<Menu> getMenuListByLevel(List<Menu> list, Integer level) {
List<Menu> newMenuList = new ArrayList<>();
for (Menu menu : list) {
if (level.equals(menu.getLevel())) {
newMenuList.add(menu);
}
}
sortMenuList(newMenuList);
return newMenuList;
}
/**
* 按照sort字段排序
*
* @param list
*/
public void sortMenuList(List<Menu> list) {
list.sort((menu1, menu2) -> {
Integer sort1 = menu1.getSort();
Integer sort2 = menu2.getSort();
return sort1.compareTo(sort2);
});
}
java返回数据库中层级结构数据的纯算法写法,以动态菜单为例的更多相关文章
- Eclipse中java向数据库中添加数据,更新数据,删除数据
前面详细写过如何连接数据库的具体操作,下面介绍向数据库中添加数据. 注意事项:如果参考下面代码,需要 改包名,数据库名,数据库账号,密码,和数据表(数据表里面的信息) package com.ning ...
- java和数据库中日期类型的常见用法
(1)java中日期类型:Date.Timestamp(2)数据库中:Date.Timestamp(3)字符串和Date之间的格式化转换: SimpleDateFormat类方法: format ...
- java和数据库中所有的锁都在这了
1.java中的锁 1.1 锁的种类 公平锁/非公平锁 可重入锁/不可重入 独享锁/共享锁 读写锁 分段锁 偏向锁/轻量级锁/重量级锁 自旋锁 1.2 锁详细介绍 1.2.1 公平锁,非公平锁 公平锁 ...
- Java删除数据库中的数据
1:删除数据库中数据表中的数据同样也是一个非常用的技术,使用executeUpdate()方法执行用来做删除SQL的语句可以删除数据库表中的数据 2:本案例使用Statement接口中的execute ...
- java更改数据库中的数据
不废话,上代码 package com.ningmeng; import java.sql.*; /** * 1:更改数据库中的数据 * @author biexiansheng * */ publi ...
- 时间、金钱在java、数据库中的变量类型之总结
在编写程序时,总是有些变量的类型搞不很明白,现将目前涉及到的变量总结一下: 1.“时间”类型 (1).在数据库中的变量类型是:DateTime 比如: operateTime DATETIME,//数 ...
- java 将数据库中的每一条数据取出放入数组或者List中
1.如何将数据库中数据按照行(即一整条数据)取出来,存入到数组当中? public static String str = null; // 将StringBuffer转化成字符串 public st ...
- 利用JAVA想数据库中提交数据
1.用户信息提交界面 <%@ page language="java" contentType="text/html; charset=UTF-8" pa ...
- Java读取数据库中的xml格式内容,解析后修改属性节点内容并写回数据库
直接附代码: 1.测试用的xml内容 <mxGraphModel> <root> <mxCell id="-1" /> <mxCell i ...
- java返回参数中几种常见的方法
1.有参数有返回值 public class text_1 { 1)创建add方法 public int add(int i, int j) { int res = i + j; ...
随机推荐
- 关于DC1的渗透报告:
打开DC1,发现我们需要登录DC1,但是我们不知道密码,所以我们只能扫描分析一下他的IP地址,在kali中我们用nmap来扫描发现 DC1的IP地址也许是192.168.42.130,我们看看他开了什 ...
- Golang 入门 : Go语言的设计哲学
前言 设计哲学之于编程语言,就好比一个人的价值观之于这个人的行为. 因为如果你不认同一个人的价值观,那你其实很难与之持续交往下去,即所谓道不同不相为谋.类似的,如果你不认同一门编程语言的设计哲学,那么 ...
- Go new函数 例子解析答疑
package main import "fmt" func main() { p1 :=new(int) *p1 =1 fmt.Println("p1",p1 ...
- mac mamp php扩展安装
官网下载需要开启的php扩展 PHP扩展下载官网地址 解压扩展包,指定mamp所使用的php版本的phpize编译安装 # 在解压的扩展包中执行以下命令 /Applications/MAMP/bin/ ...
- Docker 运行命令
停止所有的容器 docker stop $(docker ps -aq) 启动所有的容器 docker start $(docker ps -aq) 停止容器 docker stop <容器Na ...
- Delphi编写的一款锁屏小工具
Delphi编写的一款锁屏小工具,双击程序立即锁屏,木有界面的.解除锁屏密码:alt+空格. unit Unit1; interface uses Windows, Messages, SysUtil ...
- 使用ssh连接virtual Box里的虚拟机
使用ssh连接virtual Box里的虚拟机 需求:virtual Box提供的文件拖放功能在从虚拟机拖向主机时,会出现一些卡顿,因此考虑使用ssh代替其文件传输功能. 高级 -> 端口转发 ...
- BUUCTF---RSA5(低加密指数广播攻击)
题目 知识 加密指数e非常小 一份明文使用不同的模数n,相同的加密指数e进行多次加密 可以拿到每一份加密后的密文和对应的模数n.加密指数e 解密 由于模数n只能分解为p和q,所以当n很多时,p或q有相 ...
- 抽象类和接口的对比、及各自的使用场景--java进阶day02
1.区别 2.各自的使用场景 1.抽象类的使用场景 如图,有三个类,其中存在共性,我们就会写一个父类并抽取出共性的东西,但有的方法难免会描述不清,所以我们就将其写为了抽象方法,抽象方法又得存在于抽象类 ...
- Oracle chr() ascii()
函数简介 实用函数 chr() 和 ascii() chr() 函数将ASCII码转换为字符: ASCII码 –> 字符: ascii() 函数将字符转换为ASCII码: 字符 –> AS ...