如何查询多级菜单(采用递归的方法)

这篇具有很好参考价值的文章主要介绍了如何查询多级菜单(采用递归的方法)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

应用场景
1.京东
京东的页面就是这么显示的在家用电器下面有电视.空调.洗衣机然后再电视下面又有全面屏电视.教育电视等等
如何查询多级菜单(采用递归的方法),java,spring

2.我们的后端管理系统
我们后端在页面上显示的很多也是通过层级目录的显示出来。
如何实现

1.准备数据库

我们这里parent_id为0的为我们的一级菜单
如何查询多级菜单(采用递归的方法),java,spring

2. 准备我们的实体类

注意我们需要编写一个List集合来放我们的二级集合,泛型为当前类
(实体类字段对应数据库字段即可,乱码是因为使用代码生成器,可能编码没有设置好)
注意:需要加上@TableField(exist = false) 代表数据库没有这个字段,不然会报错

package com.xue.entity;

import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

/**
 * 产品类目
 */
@Data
@Accessors(chain = true)
public class StuCategory implements Serializable {
    @TableId(value = "category_id", type = IdType.AUTO)
    private Long categoryId;
    @ExcelProperty("店铺id")
    private Integer shopId;
    @ExcelProperty("产品父id")
    private Integer parentId;
    @ExcelProperty("产品类目名字")
    private String categoryName;
    @ExcelProperty("产品图片")
    private String productImage;
    @ExcelProperty("创建时间")
    private Date createTime;
    @ExcelProperty("修改时间")
    private Date updateTime;
    @ExcelProperty("排序")
    private String sort;
    //编写一个list集合来放二级集合
    @TableField(exist = false)//代表数据库没有这个字段,不然会报错
    private List<StuCategory> children;
}

3.编写Controller

package com.xue.controller;

import com.xue.entity.StuCategory;
import com.xue.service.StuCategoryService;
import com.xue.util.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

@RestController
public class StuCategoryController {

    @Resource
    private StuCategoryService stuCategoryService;

    /**
     * 查询所有分类以及子分类,并用树型结构组装起来
     * @return
     */
    @GetMapping("StuCategoryList")
    public Result<List> StuCategoryList() {
        List<StuCategory> stuCategoryList = stuCategoryService.listwithTree();
        return Result.success(stuCategoryList);
    }

}

4.编写Service方法

package com.xue.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.xue.entity.StuCategory;

import java.util.List;

public interface StuCategoryService extends IService<StuCategory> {

    List<StuCategory> listwithTree();
}

5.编写ServiceImpl

package com.xue.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xue.entity.StuCategory;
import com.xue.mapper.StuCategoryMapper;
import com.xue.service.StuCategoryService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class StuCategoryServiceImpl extends ServiceImpl<StuCategoryMapper, StuCategory> implements StuCategoryService {

    @Resource
    private StuCategoryMapper stuCategoryMapper;

    @Override
    public List<StuCategory> listwithTree() {
        //查询出所有的分类
        List<StuCategory> stuCategoryList=stuCategoryMapper.selectList(null);
        /**
         *     这段的代码的意思为调用了stream的filter过滤方法把查询出来getParentCid==0的数 因为这些都是我们的一级菜单
         *     然后查询还要查询出我们一级菜单下的二级菜单调用stream流下的map将我们的返回值重新改变一下在返回,这样把我们查询的数据set到我们的Children里面我们的Children为一个
         *     list集合,我们二级菜单的数据哪里来呢,我们就可以编写一个方法采用递归的方法查询出我们的二级菜单,我们二级菜单下面还有三级菜单
         */
        List<StuCategory> stuCategories=stuCategoryList.stream().filter((StuCategory)->{
            return StuCategory.getParentId() == 0;
        }).map((menu) -> {
            //menu当前菜单在entities找下一个菜单
            menu.setChildren(getChildrens(menu, stuCategoryList));
            return menu;
        }).sorted((menu1, menu2) -> {
            return (menu1.getSort() == null ? 0 : Integer.parseInt(menu1.getSort())) - (menu2.getSort() == null ? 0 : Integer.parseInt(menu2.getSort()));
        }).collect(Collectors.toList());
        /**2.2查出我们的一级菜单下的子菜单 我们需要在实体类中编写一个list集合放我们的子菜单,因为
         一个一级菜单下面可以有多个二级菜单
         */
        System.out.println(stuCategories);
        return stuCategories;
    }
    //递归查出所有的菜单的子菜单

    /**
     * @param root 为当前菜单
     * @param all  所有的菜单
     * @return
     * 首先调用stream的方法过滤一下  判断当前菜单的父id是否等于当前菜单的这个id。如果相同这个菜单就是这个id下的子菜单
     * 我们就调用map方法改变我们的返回值修改一下在重新返回,
     * map方法的作用为调用自己查询出下一级菜单 因为我们二级菜单下面可能有三级菜单或者四级菜单
     */
    private List<StuCategory> getChildrens(StuCategory root, List<StuCategory> all) {

        List<StuCategory> children = all.stream().filter(stuCategory -> {
            return stuCategory.getParentId() == root.getCategoryId().intValue();
        }).map(categoryEntity -> {
            //还是调用这个setChildren方法添加我们的子菜单  参数为categoryEntity为当前的菜单找,在所有菜单中找到所有的子菜单
            //categoryEntity的意思  如果当前菜单为二级菜单就调用这个方法查询这个二级菜单下的子菜单
            categoryEntity.setChildren(getChildrens(categoryEntity, all));
            return categoryEntity;
        }).sorted((menu1, menu2) -> {
            return (menu1.getSort() == null ? 0 : Integer.parseInt(menu1.getSort())) - (menu2.getSort() == null ? 0 : Integer.parseInt(menu2.getSort()));
        }).collect(Collectors.toList());
        return children;
    }
}

注意我们这里使用到了jdk8中的stream
stream中的filter方法为过滤里面可以加条件
stream中的map方法为把我们返回的数据重新改变一下在返回可以set一些新的值返回
stream中的sorted方法为把查询出的数据以那种方式排序
stream.collect(Collectors.toList())为把查询出的数据已list集合返回

看看效果吧文章来源地址https://www.toymoban.com/news/detail-633490.html

{
	"code": 200,
	"msg": "成功",
	"date": [
		{
			"categoryId": 1,
			"shopId": 1,
			"parentId": 0,
			"categoryName": "手机数码",
			"productImage": null,
			"createTime": "2023-08-07T02:56:57.000+00:00",
			"updateTime": "2023-08-07T02:57:00.000+00:00",
			"sort": "1",
			"children": [
				{
					"categoryId": 7,
					"shopId": 1,
					"parentId": 1,
					"categoryName": "手机通信",
					"productImage": null,
					"createTime": "2023-08-07T03:00:58.000+00:00",
					"updateTime": "2023-08-07T03:01:01.000+00:00",
					"sort": "1",
					"children": [
						{
							"categoryId": 8,
							"shopId": 1,
							"parentId": 7,
							"categoryName": "智能设备",
							"productImage": null,
							"createTime": "2023-08-07T03:01:22.000+00:00",
							"updateTime": "2023-08-07T03:01:23.000+00:00",
							"sort": "1",
							"children": []
						}
					]
				}
			]
		},
		{
			"categoryId": 2,
			"shopId": 1,
			"parentId": 0,
			"categoryName": "美妆护肤",
			"productImage": null,
			"createTime": "2023-08-07T02:57:22.000+00:00",
			"updateTime": "2023-08-07T02:57:25.000+00:00",
			"sort": "1",
			"children": []
		},
		{
			"categoryId": 3,
			"shopId": 1,
			"parentId": 0,
			"categoryName": "运动服饰",
			"productImage": null,
			"createTime": "2023-08-07T02:57:37.000+00:00",
			"updateTime": "2023-08-07T02:57:40.000+00:00",
			"sort": "1",
			"children": []
		},
		{
			"categoryId": 4,
			"shopId": 1,
			"parentId": 0,
			"categoryName": "酒水饮料",
			"productImage": null,
			"createTime": "2023-08-07T02:58:19.000+00:00",
			"updateTime": "2023-08-07T02:58:21.000+00:00",
			"sort": "1",
			"children": []
		},
		{
			"categoryId": 5,
			"shopId": 1,
			"parentId": 0,
			"categoryName": "珠宝钟表",
			"productImage": null,
			"createTime": "2023-08-07T02:58:37.000+00:00",
			"updateTime": "2023-08-07T02:58:39.000+00:00",
			"sort": "1",
			"children": []
		},
		{
			"categoryId": 6,
			"shopId": 1,
			"parentId": 0,
			"categoryName": "美味零食",
			"productImage": null,
			"createTime": "2023-08-07T03:00:33.000+00:00",
			"updateTime": "2023-08-07T03:00:36.000+00:00",
			"sort": "1",
			"children": []
		}
	]
}

到了这里,关于如何查询多级菜单(采用递归的方法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Python】Selenium多级悬浮菜单定位方法分享

    举例图: 以下菜单选择需逐级鼠标悬浮显示才可选择 注明: 示例代码: 本文均为本人编写,本文如有侵权请告知删除。

    2024年02月12日
    浏览(39)
  • 多级菜单 树结构 排序 前端 后端 java

    目录 省流: 正文:  v1.0版  前端传的值: 后端代码: v2.0版 v3.0版 前端提交过来整个树即可。  给整个树进行sort。代码如下: 这个只是单纯排序,没有替换parentId。升级版本见正文。 排序完以后,结果如下: 一级节点的sort:1,2,3,4... 二级节点的sort:每个一级节点下的

    2024年02月06日
    浏览(35)
  • 详解织梦dedecms5.7 无限级多级栏目菜单调用方法

    以前在用到5.7无限级栏目列表菜单时下载了网上的资料都未成功,因此我参考网上及dedecms本身的channel.lib.php及cattree.lib.php制作了调用标签。 1、在includetaglib建立randomartlist.lib.php 内容如下: {$row[\\\'typename\\\']}n\\\"; } randomartlistSon($row[\\\'id\\\'],$typeid,$currentstyle, $revalue); } if($cacheid !=\\\'\\\') { W

    2024年02月02日
    浏览(40)
  • Java 新手如何使用Spring MVC 中的查询字符串和查询参数

    目录 前言   什么是查询字符串和查询参数? Spring MVC中的查询参数  处理可选参数 处理多个值 处理查询参数的默认值 处理查询字符串 示例:创建一个RESTful服务  总结 作者简介:  懒大王敲代码,计算机专业应届生 今天给大家聊聊Java 新手如何使用Spring MVC 中的查询字符串

    2024年02月03日
    浏览(49)
  • javaScript 树形结构 递归查询方法。

    1. 函数递归定义          程序调用自身的编程技巧称为递归 ( recursion)。 2.使用条件   1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。  2.每次递归调用之后越来越接近这个限制条件。  3.既然是自己调用自己,那么整个逻辑一定是很有规律,对应的传

    2024年02月14日
    浏览(59)
  • 简易oled多级菜单实现

      最近在学习如何实现oled多级菜单时,查看了大多数博主发的文章,大概似懂的文章内容可让我好一阵思考,于是我觉得应该有一篇更加简单易懂的文章能轻易上手;我们实现项目时一定先要准备以下知识点:1. 结构体 2.结构体数组 3.函数指针 (如果还有没有这方面的C语言

    2024年02月05日
    浏览(67)
  • OLED多级菜单记录

    作为一个成熟的项目,就必然不会只有一个方面的特点了,这里一般我们可能需要系统来进行调度,然后给一些可视化的UI,当然我前面有讲到HMI串口屏的使用,串口屏确实是非常不错的UI工具,但是一些比较小的项目就用不太到了,因此这里如果是一些低成本的DIY的项目,一

    2024年02月02日
    浏览(43)
  • 基于gin关于多级菜单的处理

    多级菜单是很多业务场景需要的。下面是一种处理方式 下面是model

    2024年02月12日
    浏览(35)
  • STM32_OLED多级菜单

    程序实现 多级菜单显示实则是多个界面的跳转,这个版本更加适合初学者。我使用了两个按键,一个用来选择下一项,另一个用来确定选项。所以我们暂时叫他next键和enter键。先定义一个结构体,结构体里面有四个变量,分别代表当前索引号,next键,enter键和当前执行函数。

    2024年02月11日
    浏览(49)
  • STM32+OLED屏多级菜单显示(三)

            前面两章实现了OLED屏幕显示的基本功能,这一章就做一个多级菜单显示功能         单片机选择STM32F103C8T6最小系统板,OLED屏选择0.96寸OLED显示器,除了单片机和OLED屏之外,还需要三个按键(下一位键、确认键和返回键),当然一个按键也可以(单击、双击和长击

    2024年02月03日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包