Java构建树形结构返回前端

构建树形结构两种方法

我们在日常系统使用几乎都会遇到组织机构和行政区划的树形结构,那么如何返回树形结构给前端呢,下面是我构建行政区划树形所使用的两种方法,组织机构与其同理,数据库使用的是国产达梦数据库(同oracle)。

实体类

@Data
public class AreaTree {
    private String id;
    private String cname;
    private String pid;
    private List<AreaTree> treeList;
}

1、使用mybatis自带的递归方法

使用mybatis自带递归方法配合resultMap返回树形结构,这个方法同时适用无限层级的下钻。

(1)、sqlMapper.xml

<resultMap id="areaTreeMaps" type="com.lingxu.module.earlyWarn.vo.AreaTree">
        <id property="id" column="id" jdbcType="VARCHAR"/>
        <result property="pid" column="pid" jdbcType="VARCHAR" />
        <result property="cname" column="cname" jdbcType="VARCHAR"/>
        <collection property="treeList" select="findRegionTreeByPid"
                    ofType="com.lingxu.module.earlyWarn.vo.AreaTree" column="{pid=id}">

        </collection>
    </resultMap>

<select id="findRegionTree" resultMap="areaTreeMaps">
    SELECT ID,CNAME,PID FROM SYS_CITY WHERE ID = '320000'
</select>
<select id="findRegionTreeByPid" resultMap="areaTreeMaps">
    SELECT ID,CNAME,PID FROM SYS_CITY WHERE PID = #{pid}
</select>

(2)、sqlMapper.java

将第一个sql查询结果中的pid作为参数传值给第二个sql
    List<AreaTree> findRegionTree();
    
    List<AreaTree> findRegionTreeByPid(String pid);

(3)、sqlService.java

service直接调用第一个方法即可,返回的就是树形结构
public Result findRegionTree() {
        try {
            List<AreaTree> areaTrees = issueManageMapper.findRegionTree();
            return Result.ok(areaTrees,"查询成功");
        }catch (Exception e){
            log.error("数据查询异常",e);
            return Result.error("查询异常");
        }
    }

2、使用Java递归查询

使用Java递归方法需要修改查询sql,将所有的数据全部查询出来,然后根据根节点的pid值进行分组递归处理。

(1)、sqlMapper.xml

注:with as 语法在mysql8.0版本以下无法使用
<select id="findRegionTree" resultType="com.lingxu.module.earlyWarn.vo.AreaTree">
        WITH CTE_TEMP(ID,PID,CNAME) AS (
            SELECT ID,PID,CNAME FROM SYS_CITY WHERE PID = '320000' OR SYS_CITY.ID = '320000'
            UNION ALL
            SELECT A.ID,A.PID,A.CNAME FROM SYS_CITY A
            INNER JOIN CTE_TEMP B ON A.PID = B.ID
        )
        SELECT DISTINCT * FROM CTE_TEMP ORDER BY ID
    </select>

(2)、sqlMapper.java

List<AreaTree> findRegionTree();

(3)、sqlService.java

参数ids就是树形结构作为根节点的pid值,我这边是0,按照自己需要的值修改即可。
public Result findRegionTree() {
        try {
            List<AreaTree> areaTrees = issueManageMapper.findRegionTree();
            return Result.ok(buildTreeList(areaTrees,"0"),"查询成功");
        }catch (Exception e){
            log.error("数据查询异常",e);
            return Result.error("查询异常");
        }
    }




//处理行政区划树
    private static List<AreaTree> buildTreeList(List<AreaTree> treeList, String ids){
        //获取parentId的根节点
        List<AreaTree> areaTrees = treeList.stream().filter(item -> item.getPid().equals(ids)).collect(Collectors.toList());
        //根据parentId进行分组
        Map<String,List<AreaTree>> map = treeList.stream().collect(Collectors.groupingBy(AreaTree::getPid));
        recursionFnTree(areaTrees,map);
        return areaTrees;
    }

    private static void recursionFnTree(List<AreaTree> areaTrees,Map<String,List<AreaTree>> map){
        for(AreaTree areaTree : areaTrees){
            List<AreaTree> childList = map.get(areaTree.getId());
            areaTree.setTreeList(childList);
            if (null != childList && 0 < childList.size()){
                recursionFnTree(childList,map);
            }else {
                areaTree.setTreeList(new ArrayList<>());
            }
        }
    }
返回结构样式

在这里插入图片描述

至此使用两种构建树形结构的方法就结束了,第一种方法需要递归查询数据库,这样就导致效率变低。本地测试第一种方法返回大概需要3s左右,而第二种方法返回需要90ms,所以更推荐第二种方法。
本篇文章是个人一些见解,如有不足之处还请指出。
  • 12
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值