多级菜单 多级分类 递归实现

本文详细介绍了如何通过Java代码将数据库中的分类及其子分类信息组装成树形结构。首先在Controller中添加请求,然后在Service接口及其实现类中定义方法,利用递归查找所有菜单的子菜单。最终通过HTTP请求获取到组装好的树形结构数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
如上图
电脑/办公 菜单 里面有子菜单 电脑整机 、 电脑配件 、外设产品、 游戏设备 ...

理解为:

电脑/办公 菜单对象有一个 类型为 List<菜单>的属性 这个list里面都是菜单对象 如 电脑整机 、 电脑配件 、外设产品、 游戏设备

分级菜单
其实就是菜单对象里面有子菜单 属性
(如果数据库该表中没有这个列可以在 属性上面加 @TableField(exist = false))

class CategoryEntity{
  @TableField(exist = false)  //若表中没有该列 加Table注解,作用忽略该属性映射数据库表
private List<CategoryEntity> childrens; //菜单类里面有 菜单列表属性
}

请求发送调用流程
controller–>service—>dao
前提条件:dao中有增删改查方法、连接数据库,表中有id 和 父id 属性
开始代码:

1、在Controller中添加请求

    /**
     * 查出所有分类以及子分类、以树形结构组装起来
     */
    @RequestMapping("/list/tree")//设置自己请求路径
    public List<CategoryEntity> list(){
        List<CategoryEntity> entities = categoryService.listWithTree();//(方法名写好,clt+enter创建)
        return entities;
    }

2、在Service层中添加接口

public interface CategoryService extends IService<CategoryEntity> {

    List<CategoryEntity> listWithTree();
}

3、在service impl 中 实现接口
前提:dao里面有增删改查方法的实现

public class CategoryServiceImpl  implements CategoryService{
  //注入 dao 、
     @Autowired
     CategoryDao categoryDao;
    @Override
    public List<CategoryEntity> listWithTree() {
        //第一步查出所有分类  所有注释 [分类和菜单是一个意思]
        List<CategoryEntity> entities = categoryDao.selectList(null);//我的select方法需要传 查询条件  此处为查询所有 没有条件 null
        //第二步组装成树形结构
        // 1)找到所有一级分类 用stream流filter过滤。java8新特性
        List<CategoryEntity> level1Menus = entities.stream().filter(
                categoryEntity -> categoryEntity.getParentCid() == 0 //一级分类没有上级、父id=0
                 ).map((menu)->{menu.setChildren(getChildrens(menu,entities)); return menu;}
                 //children是categoryEntity的属性 意为该分类的子分类
                 //   private List<CategoryEntity> childrens;
                 //getChildrens() 是递归查找子分类的方法 方法的实现在下面
                 //menu 是需要被查找子分类的菜单    entities 是第一步查找出的所有分类内容
                 ).collect(Collectors.toList());//最后转为list集合 
         return level1Menus;

    }
    //递归查找所有菜单的子菜单  两个参数root是需要被查找子分类的菜单(当前菜单)、all是所有的分类菜单
    private List<CategoryEntity> getChildrens(CategoryEntity root,List<CategoryEntity> all){
        List<CategoryEntity> menuChildren = all.stream().filter(categoryEntity -> {
            //对all所有的菜单进行过滤
            return categoryEntity.getParentCid() == root.getCatId();
            //过滤条件: all所有菜单的父id 是否等于 root当前菜单的id  相等,root菜单就是它的父菜单
        }).map(categoryEntity -> {  //把过滤出的子分类 setChildren 给 root当前菜单
            categoryEntity.setChildren(getChildrens(categoryEntity, all));
            return categoryEntity;
        }).collect(Collectors.toList());
        return menuChildren;
    }}

代码完成后测试

启动服务器,地址栏输入(写自己设置的请求 RequestMapping(/list/tree))

http://localhost:8080/list/tree

在这里插入图片描述
按F12(如果没显示就F5 刷新请求)
在这里插入图片描述
打开tree 在preview中可以看到 data 数据内容
在这里插入图片描述
在这里插入图片描述
测试完成!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值