Java之使用递归查询多级树形结构数据(多级菜单)

1:数据库表

字段resource_id为自增主键,其中最顶级的菜单的父类ID是用-1表示的,下面我们就来查询这张表
在这里插入图片描述

2:实体类

childMenu是用于装子类数据的;@TableField(exist = false)表示该属性不为数据库表字段,但是必须使用

package org.jeecg.modules.system.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.util.List;


@Data
@TableName("sys_depart_Manage")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="部门对象", description="部门对象")
public class SysDepartManage {
	
	/**部门名称*/
    @ApiModelProperty(value = "部门名称")
	private String departName;

	/**资源id*/
	@ApiModelProperty(value = "资源id")
	@TableId(type = IdType.AUTO)
	private Integer resourceId;

	/**父id*/
	@ApiModelProperty(value = "父id")
	private String parentId;

	/**是否展示*/
	@ApiModelProperty(value = "是否展示")
	private Integer showInput;


	/**创建时间*/
	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @ApiModelProperty(value = "创建时间")
	private Date createTime;

	/**更新时间*/
	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @ApiModelProperty(value = "更新时间")
	private Date updateTime;

	/** 子类菜单数据 */
	@TableField(exist = false)
	private List<SysDepartManage> childMenu;


}

3:controller层代码


	@Resource
    private ISysDepartManageService sysDepartManageService;
	/**
     * 部门树形查询
     * @param parentID
     * @return
     */
    @GetMapping("/menu")
    @ApiOperation(value="部门树形查询", notes="部门树形查询")
    public List<SysDepartManage> findMenu(@RequestParam String parentID) {
        return sysDepartManageService.findMenu(parentID);
    }

4:service层代码(

package org.jeecg.modules.system.service;

import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.SysDepartManage;
import java.util.List;
import java.util.Map;

public interface ISysDepartManageService extends IService<SysDepartManage> {

    List<SysDepartManage> findMenu(String parentID );

}

5:方法1:serviceimpl层代码(多次查询数据库,耗性能)

package org.jeecg.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.system.entity.SysDepartManage;
import org.jeecg.modules.system.mapper.SysDepartManageMapper;
import org.jeecg.modules.system.service.ISysDepartManageService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * @Description: 部门角色
 * @Author: jeecg-boot
 * @Date:   2020-02-12
 * @Version: V1.0
 */
@Service
public class SysDepartManageServiceImpl extends ServiceImpl<SysDepartManageMapper, SysDepartManage> implements ISysDepartManageService {

    @Override
    public List<SysDepartManage> findMenu(String parentID) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        //查询条件
        queryWrapper.eq("parent_id", parentID);
        List<SysDepartManage> list = baseMapper.selectList(queryWrapper);
        for (SysDepartManage departManage : list) {
            //递归子类数据
            departManage.setChildMenu(findMenu(departManage.getResourceId().toString()));
        }
        return list;
    }
}

6:方法2:serviceimpl层代码(只查询数据库1次)

package org.jeecg.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.system.entity.SysDepartManage;
import org.jeecg.modules.system.mapper.SysDepartManageMapper;
import org.jeecg.modules.system.service.ISysDepartManageService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Service
public class SysDepartManageServiceImpl extends ServiceImpl<SysDepartManageMapper, SysDepartManage> implements ISysDepartManageService {


    @Override
    public List<SysDepartManage> findMenu(String parentID) {
        //数据查询
        List<SysDepartManage> list = baseMapper.selectList(new QueryWrapper());
        //新建一个用于接收数据的list
        List<SysDepartManage> resultList = new ArrayList<>();
        for (SysDepartManage result : list) {
            if (result.getParentId() == 0) {
                //调用方法给子类添加数据
                resultList.add(getMenuTree(result, list));
            }
        }
        return resultList;
    }

    private SysDepartManage getMenuTree(SysDepartManage result, List<SysDepartManage> list) {
        for (SysDepartManage sysDepartManage : list) {
            //如果父类主键等于传过来实体类的ID
            if (sysDepartManage.getParentId().equals(result.getResourceId())) {
                if (result.getChildMenu() == null) {
                    result.setChildMenu(new ArrayList<>());
                }
                // 递归调用
                result.getChildMenu().add(getMenuTree(sysDepartManage, list));
            }
        }
        return result;
    }

}

7:mapper层代码

package org.jeecg.modules.system.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.system.entity.SysDepartManage;
import java.util.List;
import java.util.Map;


public interface SysDepartManageMapper extends BaseMapper<SysDepartManage> {
    
}

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
/** * 根据等级查询类目树 * * @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; }
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值