二级分类菜单及三级分类菜单的层级结构返回

前言

在开发投诉分类功能模块时,遇到过这样一个业务场景:后端需要按层级结构返回二级分类菜单所需数据,换言之,将具有父子关系的List结果集数据转为树状结构数据来返回

二级分类菜单

前期准备

这里简单复刻下真实场景中 出现的二级分类菜单层级结构返回

数据库设计

建表语句如下

DROP TABLE IF EXISTS `menu`;
CREATE TABLE `menu`  (`id` bigint NOT NULL AUTO_INCREMENT,`name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '名称',`parent_id` bigint NULL DEFAULT NULL COMMENT '父级id',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = DYNAMIC;-- ----------------------------
-- Records of menu
-- ----------------------------
INSERT INTO `menu` VALUES (1, '质量问题', 0);
INSERT INTO `menu` VALUES (2, '变质', 1);
INSERT INTO `menu` VALUES (3, '过期', 1);
INSERT INTO `menu` VALUES (4, '包装破损', 1);
INSERT INTO `menu` VALUES (5, '服务问题', 0);
INSERT INTO `menu` VALUES (6, '态度恶劣', 5);
INSERT INTO `menu` VALUES (7, '东拉西扯', 5);

在这里插入图片描述

效果图预览

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里是在SpringBoot项目中演示实现的,持久层框架选用MyBatis-Plus,版本号:3.5.3.1

🌟之所以强调MP版本号,是因为之前在实现分页时遇过挫,真实项目选用的版本是3.3.2,而自己在学习MP时,选择版本是3.5.3.1。MP官方文档在不同版本中,有关分页插件的使用介绍可能存在不同,实际开发中对引入MP依赖的版本号还是要有所关注

在这里插入图片描述

开发测试

创建实体类

package com.atguigu.mybatisplus.pojo;import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;/*** @author Songguo* @date 2023/11/15 9:56*/
@Data
@TableName("menu")
public class Menu {private Long id;private String name;private Long parentId;
}

创建mapper层

package com.atguigu.mybatisplus.mapper;import com.atguigu.mybatisplus.pojo.Menu;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;public interface MenuMapper extends BaseMapper<Menu> {
}

创建service层接口及实现类

package com.atguigu.mybatisplus.service;import com.atguigu.mybatisplus.pojo.Menu;
import com.baomidou.mybatisplus.extension.service.IService;public interface MenuService extends IService<Menu> {
}
package com.atguigu.mybatisplus.service.impl;import com.atguigu.mybatisplus.mapper.MenuMapper;
import com.atguigu.mybatisplus.pojo.Menu;
import com.atguigu.mybatisplus.service.MenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;/*** @author Songguo* @date 2023/11/15 10:00*/
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
}

创建测试类

package com.atguigu.mybatisplus;import com.atguigu.mybatisplus.pojo.Menu;
import com.atguigu.mybatisplus.service.MenuService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @author Songguo* @date 2023/11/15 10:02*/
@SpringBootTest
public class MenuServiceImplTest {@Autowiredprivate MenuService menuService;@Testpublic void ListToTreeTest() {List<Menu> list = menuService.list();// 存放要返回的树状结构数据List<Map<String, Object>> MenuList = new ArrayList<>();for (Menu menu : list) {if (Long.valueOf(0) == menu.getParentId()) {Map<String, Object> map = new HashMap<>();map.put("id", menu.getId());map.put("name", menu.getName());// map.put("parentId", menu.getParentId());map.put("children", getChildren(list, menu.getId()));MenuList.add(map);}}MenuList.forEach(System.out::println);}public List<Map<String, Object>> getChildren(List<Menu> list, Long topId) {List<Map<String, Object>> data = new ArrayList<>();for (Menu menu : list) {if (topId == menu.getParentId()) {Map<String, Object> map = new HashMap<>();map.put("id", menu.getId());map.put("name", menu.getName());// map.put("parentId", menu.getParentId());data.add(map);}}return data;}}

注意: 在真实场景中,并不需要返回每条记录的所有字段值,主要看前端需要接收那些数据

实现思路很简单:

1️⃣获取分类菜单所有记录

2️⃣遍历找出一级节点(父节点),然后在调用getChildren()(重金寻子方法)获取二级节点(子节点)

3️⃣通过List<Map<String,Object>>来存放结果集

三级分类菜单

前期准备

这里简单复刻下真实场景中 出现的三级分类菜单层级结构返回

数据库设计

建表语句如下

CREATE TABLE address (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50) NOT NULL,parent_id INT NOT NULL,level INT NOT NULL
);INSERT INTO address (name, parent_id, level) VALUES ('湖北', 0, 1);
INSERT INTO address (name, parent_id, level) VALUES ('辽宁', 0, 1);
INSERT INTO address (name, parent_id, level) VALUES ('武汉', 1, 2);
INSERT INTO address (name, parent_id, level) VALUES ('荆州', 1, 2);
INSERT INTO address (name, parent_id, level) VALUES ('沈阳', 2, 2);
INSERT INTO address (name, parent_id, level) VALUES ('蔡甸区', 3, 3);
INSERT INTO address (name, parent_id, level) VALUES ('江夏区', 3, 3);
INSERT INTO address (name, parent_id, level) VALUES ('沙市区', 4, 3);
INSERT INTO address (name, parent_id, level) VALUES ('大东区', 5, 3);
INSERT INTO address (name, parent_id, level) VALUES ('浑南区', 5, 3);

在这里插入图片描述

效果图预览

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

开发测试

创建实体类

package com.atguigu.mybatisplus.pojo;import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;/*** @author Songguo* @date 2023/11/26 17:04*/
@Data
@TableName("address")
public class Address {private int id;private String name;private int parentId;private int level;
}

创建mapper层

package com.atguigu.mybatisplus.mapper;import com.atguigu.mybatisplus.pojo.Address;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;public interface AddressMapper extends BaseMapper<Address> {
}

创建service层接口及实现类

package com.atguigu.mybatisplus.service;import com.atguigu.mybatisplus.pojo.Address;
import com.baomidou.mybatisplus.extension.service.IService;public interface AddressService extends IService<Address> {
}
package com.atguigu.mybatisplus.service.impl;import com.atguigu.mybatisplus.mapper.AddressMapper;
import com.atguigu.mybatisplus.pojo.Address;
import com.atguigu.mybatisplus.service.AddressService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;/*** @author Songguo* @date 2023/11/26 17:08*/
@Service
public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> implements AddressService {
}

创建测试类

package com.atguigu.mybatisplus;import com.atguigu.mybatisplus.pojo.Address;
import com.atguigu.mybatisplus.service.AddressService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @author Songguo* @date 2023/11/26 17:10*/
@SpringBootTest
public class AddressServiceImplTest {@Autowiredprivate AddressService addressService;@Testpublic void getAddress() {List<Address> list = addressService.list();// list.forEach(System.out::println);// 存放结果集List<Map<String, Object>> addressList = new ArrayList<>();for (Address address : list) {if (address.getLevel() == 1) {Map<String, Object> map = new HashMap<>();map.put("id", address.getId());map.put("name", address.getName());// map.put("parentId", address.getParentId());map.put("children", getChildren(list, address.getId()));addressList.add(map);}}addressList.forEach(System.out::println);}public List<Map<String, Object>> getChildren(List<Address> list, int parentId) {List<Map<String, Object>> data = new ArrayList<>();for (Address address : list) {HashMap<String, Object> map = new HashMap<>();if (parentId == address.getParentId()) {map.put("id", address.getId());map.put("name", address.getName());// map.put("parentId", address.getParentId());if (address.getLevel() < 3) {map.put("children", getChildren(list, address.getId()));}data.add(map);}}return data;}}

小结

二级分类菜单的层级结构返回是在真实项目中遇到的,而三级分类菜单的层级结构返回是模拟真实场景下的需求进行扩展实现的

弄懂了二级分类和三级分类,多级分类还会远嘛

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/185207.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Doris 简介(一)

Apache Doris 由百度大数据部研发&#xff08;之前叫百度 Palo&#xff0c;2018 年贡献到 Apache 社区后&#xff0c;更名为 Doris &#xff09;&#xff0c;在百度内部&#xff0c;有超过 200 个产品线在使用&#xff0c;部署机器超过 1000 台&#xff0c;单一业务最大可达到上…

leetcode:循环队列

题目描述 题目链接&#xff1a;622. 设计循环队列 - 力扣&#xff08;LeetCode&#xff09; 题目分析 我们开辟空间的时候多开一个&#xff0c;k是队列的长度&#xff0c;我们开k1个空间&#xff0c;定义一个front指向头&#xff0c;back的下一个指向尾 当frontback的时候&am…

C++ 学习笔记——C++纯虚函数和抽象类

C纯虚函数 什么是纯虚函数 1&#xff0c;纯虚函数只有函数名、参数、返回值类型。 2&#xff0c;纯虚函数的定义是在函数句首使用 virtual 关键字修饰&#xff0c;并且在句末增加 “ 0”。 virtual void funtion() 0;3&#xff0c;纯虚函数只有声明&#xff0c;基类可以存…

05、基于梯度下降的协同过滤算法

05、基于梯度下降的协同过滤算法理论与实践Python 开始学习机器学习啦&#xff0c;已经把吴恩达的课全部刷完了&#xff0c;现在开始熟悉一下复现代码。对这个手写数字实部比较感兴趣&#xff0c;作为入门的素材非常合适。 协同过滤算法是一种常用的推荐算法&#xff0c;基于…

新型信息基础设施下的IP追溯技术:构建数字化安全新境界

随着新型信息基础设施的快速发展&#xff0c;IP&#xff08;Internet Protocol&#xff09;追溯技术在数字化安全领域变得愈发重要。IP追溯不仅能够帮助识别网络攻击源&#xff0c;提升网络安全水平&#xff0c;还有助于数字证据追踪、合规性审计等方面。本文将探讨新型信息基础…

Vue 和 React 的优点分别是什么?如何选择?

目录 为什么我更喜欢Vue&#xff1f; 低代码平台的前端框架采用Vue的优势有哪些&#xff1f; JNPF-Web-Vue3 的技术栈介绍 &#xff08;1&#xff09;Vue3.x &#xff08;2&#xff09;Vue-router4.x &#xff08;3&#xff09;Vite4.x &#xff08;4&#xff09;Ant-D…

『Jmeter超级干货』| Linux下Jmeter安装配置、脚本设计执行、监控及报告完整过程

『Jmeter超级干货』| Linux下Jmeter安装配置、脚本设计执行、监控及报告完整过程 1 JDK安装部署1.1 JDK下载1.2 JDK配置 2 Jmeter安装部署2.1 Jmeter下载2.2 Jmeter安装2.3 Jmeter相关目录配置2.4 Jmeter启动配置2.5 检查并启动 3 Jmeter汉化3.1 临时修改3.2 永久修改 4 准备测…

docker 学习总结

docker 概念 -云计算的基石 docker的一个软件&#xff1a; 开源 docker基本组成 docker主机(Host)&#xff1a;安装了Docker程序的机器&#xff08;Docker直接安装在操作系统之上&#xff09;&#xff1b; docker仓库(Registry)&#xff1a;用来保存各种打包好的软件镜像&a…

中信建投在金融电于化期刊发布 DataOps 实践

文 ‖ 中信建投证券股份有限公司 马丽霞 高宇航 李可 许哲 李海伟 近年来&#xff0c;数据的分析和应用对各行各工业的业务模式和竞争形态进行重塑&#xff0c;而积极应对挑战和顺应时代变化是各个市场参与者的必选项。作为资本市场数字化转型的领航者&#xff0c;中信建投证券…

【meta】Scaling Speech Technology to 1,000+ Languages

nvidia-NeMo包含TTS的模型&#xff0c;开源数据 uroma转写工具介绍 uroman转写工具 N-to-M mapping 转写的规范&#xff0c;包含一些中文-拼音&#xff0c;拉丁文-读法的规则转换。字符串匹配规则下的查字典&#xff1b; 将字母对应到发音单元 转写规范 转写过程尽量做到可…

打字练习--Master of Typing 3

Master of Typing 3是一款适用于Mac OS平台的打字速度提升和键盘技能训练软件。它旨在帮助用户提高打字速度、准确性和键盘操作技能&#xff0c;无论用户是初学者还是熟练的键盘操作者&#xff0c;都能提供适合的练习模式。Master of Typing 3提供了一系列结构化的打字课程和实…

(2023码蹄杯)省赛(初赛)第二场真题(原题)(题解+AC代码)

题目1&#xff1a;MC0214捡麦子 码题集OJ-捡麦子 (matiji.net) 思路: 1.第n米在前n-1米的基础上多加一个n个麦子&#xff0c;那么直接从1开始枚举&#xff0c;累加答案即可 AC_Code:C #include<bits/stdc.h> using namespace std;int main( ) {int n; cin>>n;…

三维模型重建中地面控制点刺点输入常见问题及解决方法

三维模型重建中地面控制点刺点输入常见问题及解决方法 在倾斜摄影三维模型重建中&#xff0c;地面控制点的人工刺点输入是一个重要的环节。然而&#xff0c;这个过程可能会遇到一些常见问题。以下是一些常见问题及相应的解决方法&#xff1a; 1、问题&#xff1a;标定点位置不…

路由跳转到另一个页面

点击添加员工跳转到详情页 <el-button size"mini" type"primary" click"$router.push(/employee/detail)">添加员工</el-button>配置员工详情的路由信息 import layout from "/layout"; export default {path: "/em…

OBC、DCDC自动化测试解决方案!

OBC(车载充电机&#xff09;和DCDC&#xff08;直流-直流变换器&#xff09;是电动汽车的核心部件&#xff0c;DCDC和OBC的功能质量对于整车的性能和安全性至关重要。在OBC和DCDC&#xff0c;以及整车开发测试过程中&#xff0c;需要对OBC和DCDC进行功能和性能方面进行全面的测…

水溶性肥料行业分析:预计2028年将达到202亿美元

随着我国农业的集约化、规模化不断发展&#xff0c;以及大型农场涌现&#xff0c;水肥一体化面积将会不断扩大。同时&#xff0c;水溶肥是符合更加环保、更加可持续发展的新一代肥料&#xff0c;是中国肥料产业未来的重点发展课题。 水溶性肥料(Water Soluble Fertilizer&…

ChatGPT生成的一些有趣的文件管理用python小程序

1. 在前位置中的所有文件夹内增加一个名为 abc 的新文件夹 import osdef create_abc_directories(root_dir.):# 获取当前目录下的所有目录subdirectories [d for d in os.listdir(root_dir) if os.path.isdir(os.path.join(root_dir, d))]# 在每个目录中创建名为abc的子目录f…

Android自动化测试中使用ADB进行网络状态管理!

技术分享&#xff1a;使用ADB进行Android网络状态管理 Android自动化测试中的网络状态切换是提高测试覆盖率、捕获潜在问题的关键步骤之一&#xff0c;本文将介绍 如何使用ADB检测和管理Android设备的网络状态。 自动化测试中的网络状态切换变得尤为重要。 网络状态查询 adb s…

【23真题】复录比高达2.24,但题目很棒!

今天分享的是23年广东工业837的信号与系统试题及解析。注意官方不公示真题&#xff0c;所以这套试卷为回忆版本。 本套试卷难度分析&#xff1a;22年广东工业837考研真题&#xff0c;我也发布过&#xff0c;若有需要&#xff0c;戳这里自取&#xff01;平均分107.93&#xff…

Java中的Lambda表达式

lambda表达式是一个可传递的代码块&#xff0c;可以在以后执行一次或多次。 1.lambda表达式的语法 eg&#xff1a;有如下lambda表达式&#xff1a; (int a, int b) -> {return ab}; 这个表达式的本质是一个函数。 一般的函数类似如下&#xff1a; int add(int a, int …