java实现递归查询树形结构数据

数据库表(还有一个brforeId)

 建一个返回菜单数据的实体类user

package com.example.domain;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.List;

@Data
@TableName("user")
public class User {

    @TableField("user_id")
    private Long userId;

    @TableField("user_name")
    private String userName;

    @TableField("phone")
    private String phone;

    @TableField("user_password")
    private String userPassword;

    @TableField("parent_id")
    private Long parentId;

    @TableField("before_id")
    private Long beforeId;

    @TableField(exist = false)
    private List<User> child;
}

 注:这里省略了get,set方法,childMenu是用于装子类数据的;@TableField(exist = false)表示该属性不为数据库表字段,但是必须使用

业务实现层代码:

package com.example.service;

import com.example.domain.User;

import java.util.List;

public interface UserService {

    /**
     * 获取多级菜单信息
     * @param parentId
     * @return
     */
    List<User> find(Long parentId);

    /**
     *递归查询多级  这是常用的
     * @return
     */
    List<User> find2();

    /**
     * 递归查询多级 并且同级要排序
     * @return
     */
    List<User> find3();

}
package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.domain.User;
import com.example.mapper.UserMapper;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> find(Long parentId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getParentId, parentId);
        List<User> list = userMapper.selectList(queryWrapper);
        for (User user : list) {
            //递归
            user.setChild(find(user.getUserId()));
        }
        return list;
    }

    @Override
    public List<User> find2() {
        //返回
        List<User> result = new ArrayList<>();
        //查出一级菜单
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getParentId, 0);
        List<User> list = userMapper.selectList(queryWrapper);

        //所有数据
        List<User> allList = userMapper.selectList(null);
        //遍历一级菜单
        for (User user : list) {
            //调用递归==================
            user.setChild(getChildren(user.getUserId(), allList));
            result.add(user);
        }
        return result;
    }

    //当前级id  所有的

    private List<User> getChildren(Long id, List<User> allList) {
        //筛选出满足下一级的
        List<User> list = new ArrayList<>();
        for (User user : allList) {
            if (user.getParentId() == id) {
                list.add(user);
            }
        }
        if (list == null) {
            return null;
        }

        for (User user : list) {
            user.setChild(getChildren(user.getUserId(), allList));
        }
        return list;
    }

    //==================================

    @Override
    public List<User> find3() {
        //返回结果
        List<User> result = new ArrayList<>();
        //查询一级菜单
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getParentId, 0);
        List<User> list = userMapper.selectList(queryWrapper);
        //对一级菜单进行排序
        List<User> list1 = sortMenu(list);
        //所有菜单
        List<User> allList = userMapper.selectList(null);
        //遍历一级菜单
        for (User user : list1) {
            user.setChild(getChildren2(user.getUserId(), allList));
            result.add(user);
        }
        return result;
    }

    private List<User> getChildren2(Long userId, List<User> allList) {
        //查出符合条件的菜单
        List<User> list = new ArrayList<>();
        for (User user : allList) {
            if (user.getParentId() == userId) {
                list.add(user);
            }
        }
        //list.size() == 0 这里很重要 之前没写 直接传过去一个null过去排序 所以会报错
        if (CollectionUtils.isEmpty(list)) {  //list == null || list.size() == 0
            return new ArrayList<>();
        }

        List<User> list1 = sortMenu(list);
        //遍历
        for (User user : list1) {
            user.setChild(getChildren2(user.getUserId(),allList));
        }

        return list1;
    }

    //对同一级的菜单排序
    private List<User> sortMenu(List<User> list) {
        //定义HashMap<beforeID,User>
        HashMap<Long,User> map = new HashMap<>();
        //遍历list 把所有都加入到hashmap里
        for (User user : list) {
            map.put(user.getBeforeId(),user);
        }
        //找到beforeid为0的 即为第一个
        User user = map.get(0L);  //这个id也是下一个的beforeId
        //返回
        List<User> res = new ArrayList<>();
        res.add(user);
        while (true) {
            Long userId = user.getUserId();
            user = map.get(userId);
            if (user == null) break;
            res.add(user);
        }

        return res;
    }
}

 控制层代码:

package com.example.controller;

import com.example.domain.User;
import com.example.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
@RequestMapping("users")
public class UserController {

    @Resource
    private UserService userService;

    @GetMapping("menu")
    public List<User> find(@RequestParam Long parentId) {
        return userService.find(parentId);
    }

    @GetMapping
    public List<User> find2() {
        return userService.find2();
    }

    @GetMapping("1")
    public List<User> find3() {
        return userService.find3();
    }
}

测试

localhost:8080/users 

localhost:8080/users /1

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
/** * 根据等级查询类目树 * * @param level * @return */ @Override public List queryCategoryTree(Integer level) { //查询当前级别下类目 List list = categoryDAO.list(level); //组装好的类目树,返回前端 List categoryTree = new ArrayList(); //所有类目 List allDTOList = new ArrayList(); if (CollectionUtils.isEmpty(list)) { return categoryTree; } for (CategoryDO categoryDO : list) { allDTOList.add(new CategoryTreeDTO().convertDOToDTO(categoryDO)); } //当前等级类目 categoryTree = allDTOList.stream().filter(dto -> level.equals(dto.getLevel())).collect(Collectors.toList()); for (CategoryTreeDTO categoryTreeDTO : categoryTree) { //组装类目为树结构 assembleTree(categoryTreeDTO, allDTOList,Constants.CATEGORY_MAX_LEVEL - level); } return categoryTree; } /** * 组装树 * * @param categoryTreeDTO * @param allList * @param remainRecursionCount 剩余递归次数 * @return */ public CategoryTreeDTO assembleTree(CategoryTreeDTO categoryTreeDTO, List allList, int remainRecursionCount) { remainRecursionCount--; //最大递归次数不超过Constants.CATEGORY_MAX_LEVEL-level次,防止坏数据死循环 if(remainRecursionCount < 0){ return categoryTreeDTO; } String categoryCode = categoryTreeDTO.getCategoryCode(); Integer level = categoryTreeDTO.getLevel(); //到达最后等级树返回 if (Constants.CATEGORY_MAX_LEVEL == level) { return categoryTreeDTO; } //子类目 List child = allList.stream().filter(a -> categoryCode.equals(a.getParentCode())).collect(Collectors.toList()); if (null == child) { return categoryTreeDTO; } categoryTreeDTO.setChildren(child); //组装子类目 for (CategoryTreeDTO dto : child) { assembleTree(dto, allList,remainRecursionCount); } return categoryTreeDTO; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最后一只暴龙战士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值