Java递归查询树形结构(详解)

一.数据准备

数据库表结构如下所示,

INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (1, 0, '合伙企业');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (2, 0, '有限公司');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (3, 0, '股份有限公司');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (4, 0, '政府');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (5, 0, '行政与事业单位');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (6, 0, '协会');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (7, 0, '公益机构');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (101, 1, '有限合伙');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (102, 1, '普通合伙');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (201, 2, '一人有限公司');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (202, 2, '合资公司');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (301, 3, '上市股份公司');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (302, 3, '非上市股份公司');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (401, 4, '党办机构');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (402, 4, '中央政府');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (403, 4, '省级政府');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (404, 4, '市级政府');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (405, 4, '县区级政府');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (406, 4, '乡镇政府');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (501, 5, '行政机关');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (502, 5, '事业单位');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (601, 6, '行业协会');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (602, 6, '社会团体');
INSERT INTO `jg_user`.`com_type`(`type_id`, `parent_id`, `type_name`) VALUES (701, 7, '公益机构');
 

二.控制层代码编写

    @Log(title = "查询机构类型树", businessType = BusinessType.OTHER)
    @PostMapping("/selectComTypeTrees")
    public AjaxResult selectComTypeTrees(@RequestBody ComType comType) {
        AjaxResult ajax = AjaxResult.success();
        ajax.put("comTypeTrees", comMainService.selectComTypeTrees(comType));
        return ajax;
    }

三.业务层代码编写

@Override
    public List<ComType> selectComTypeTrees(ComType comType) {
        List<ComType> comTypeList = comMainMapper.selectComTypeTrees(comType);

        List<ComType> collect = comTypeList.stream()
                .filter(item -> item.getParentId() == 0)
                .map(item -> {
                    item.setChildList(getChildren(item, comTypeList));
                    return item;
                })
                .collect(Collectors.toList());
        return collect.size() == 0 ? comTypeList : collect;

    }


    public static List<ComType> getChildren(ComType comType, List<ComType> comTypeList) {
        List<ComType> collect = comTypeList.stream()
                .filter(item -> item.getParentId().equals(comType.getTypeId()))
                .map(item -> {
                    item.setChildList(getChildren(item, comTypeList));
                    return item;
                })
                .collect(Collectors.toList());
        return collect;
    }

四.数据库层代买编写

 <resultMap type="com.ruoyi.user.domain.ComType" id="ComTypeResult">
        <result property="typeId"    column="type_id"    />
        <result property="parentId"    column="parent_id"    />
        <result property="typeName"    column="type_name"    />
    </resultMap>
    <select id="selectComTypeTrees" parameterType="com.ruoyi.user.domain.ComType" resultMap="ComTypeResult">
        select type_id,parent_id,type_name from com_type
        <where>
            <if test="parentId != null and parentId != '' "> and parent_id = #{parentId}</if>
        </where>
    </select>

五.测试

http://localhost:8080/user/com/selectComTypeTrees

入参:

{
    "parentId": 0
}

出参:

{
	"msg": "操作成功",
	"code": 200,
	"comTypeTrees": [
		{
			"typeId": 1,
			"parentId": 0,
			"typeName": "合伙企业",
			"childList": [
				{
					"typeId": 101,
					"parentId": 1,
					"typeName": "有限合伙",
					"childList": [
						{
							"typeId": 101001,
							"parentId": 101,
							"typeName": "测试三级菜单",
							"childList": []
						}
					]
				},
				{
					"typeId": 102,
					"parentId": 1,
					"typeName": "普通合伙",
					"childList": []
				}
			]
		},
		{
			"typeId": 2,
			"parentId": 0,
			"typeName": "有限公司",
			"childList": [
				{
					"typeId": 201,
					"parentId": 2,
					"typeName": "一人有限公司",
					"childList": []
				},
				{
					"typeId": 202,
					"parentId": 2,
					"typeName": "合资公司",
					"childList": []
				}
			]
		},
		{
			"typeId": 3,
			"parentId": 0,
			"typeName": "股份有限公司",
			"childList": [
				{
					"typeId": 301,
					"parentId": 3,
					"typeName": "上市股份公司",
					"childList": []
				},
				{
					"typeId": 302,
					"parentId": 3,
					"typeName": "非上市股份公司",
					"childList": []
				}
			]
		},
		{
			"typeId": 4,
			"parentId": 0,
			"typeName": "政府",
			"childList": [
				{
					"typeId": 401,
					"parentId": 4,
					"typeName": "党办机构",
					"childList": []
				},
				{
					"typeId": 402,
					"parentId": 4,
					"typeName": "中央政府",
					"childList": []
				},
				{
					"typeId": 403,
					"parentId": 4,
					"typeName": "省级政府",
					"childList": []
				},
				{
					"typeId": 404,
					"parentId": 4,
					"typeName": "市级政府",
					"childList": []
				},
				{
					"typeId": 405,
					"parentId": 4,
					"typeName": "县区级政府",
					"childList": []
				},
				{
					"typeId": 406,
					"parentId": 4,
					"typeName": "乡镇政府",
					"childList": []
				}
			]
		},
		{
			"typeId": 5,
			"parentId": 0,
			"typeName": "行政与事业单位",
			"childList": [
				{
					"typeId": 501,
					"parentId": 5,
					"typeName": "行政机关",
					"childList": []
				},
				{
					"typeId": 502,
					"parentId": 5,
					"typeName": "事业单位",
					"childList": []
				}
			]
		},
		{
			"typeId": 6,
			"parentId": 0,
			"typeName": "协会",
			"childList": [
				{
					"typeId": 601,
					"parentId": 6,
					"typeName": "行业协会",
					"childList": []
				},
				{
					"typeId": 602,
					"parentId": 6,
					"typeName": "社会团体",
					"childList": []
				}
			]
		},
		{
			"typeId": 7,
			"parentId": 0,
			"typeName": "公益机构",
			"childList": [
				{
					"typeId": 701,
					"parentId": 7,
					"typeName": "公益机构",
					"childList": []
				}
			]
		}
	]
}

尽自己的一些绵薄之力,希望对大家有所帮助,谢谢!^_^

/** * 根据等级查询类目树 * * @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; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mr Tang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值