通过Java的Stream流将List转为树形结构

前言

日常开发中可能会遇到一些需求,比如构建菜单,构建树形结构,数据库一般就使用父id来表示,为了降低数据库的查询压力,我们可以使用Java8中的Stream流一次性把数据查出来,然后通过流式处理,转为树形结构。下面我们一起来看看怎么做。

1. 首先数据库菜单资源表数据如下:

通过Java的Stream流将List转为树形结构_第1张图片

2. SysMenuMapper.xml中SQL如下:


<mapper namespace="com.pfms.master.mapper.SysMenuMapper">

    
    <resultMap id="BaseResultMap" type="com.pfms.master.entity.SysMenu">
        <id column="ID" property="id" />
        <result column="URL" property="url" />
        <result column="PATH" property="path" />
        <result column="COMPONENT" property="component" />
        <result column="NAME" property="name" />
        <result column="ICON" property="icon" />
        <result column="PARENT_ID" property="parentId" />
        <result column="KEEP_ALIVE" property="keepAlive" />
        <result column="REQUIRE_AUTH" property="requireAuth" />
        <result column="ENABLED" property="enabled" />
        <result column="REMARK" property="remark" />
        <result column="CREATE_BY" property="createBy" />
        <result column="CREATE_DATE" property="createDate" />
        <result column="UPDATE_BY" property="updateBy" />
        <result column="UPDATE_DATE" property="updateDate" />
        
        <association property="meta" javaType="com.pfms.master.entity.domain.Meta">
            <result column="keepAlive" property="keepAlive"/>
            <result column="requireAuth" property="requireAuth"/>
        association>
    resultMap>

    <select id="getMenusByUserId_" resultMap="BaseResultMap">
        SELECT
            *
        FROM
            `sys_menu`
        WHERE
            ID IN ( SELECT MENU_ID FROM sys_menu_role WHERE ROLE_ID IN ( SELECT ROLE_ID FROM sys_user_role WHERE USER_ID = #{userId} ) )
            AND PATH IS NOT NULL
            AND PATH != ''
        ORDER BY
            ID
    select>

mapper>

3. 主要代码
/* 另一种形式 */
List<SysMenu> menus = baseMapper.getMenusByUserId_(userId);
if (isNotEmpty(menus)) {
     
    // 递归获取菜单树形结构
    // 获取父节点,说明:父节点的parentId都是1(根节点是0)
    resultMenus = menus.stream().filter(m -> m.getParentId() == 1).peek(
            (m) -> m.setChildren(getChildren(m, menus))
    ).collect(Collectors.toList());
}
4. 递归获取子节点的方法
/**
* 递归获取子节点
*
* @param m
* @param menus
* @return java.util.List
* @author chao.zhang
* @date 2020/10/20 17:57
**/
private List<SysMenu> getChildren(SysMenu m, List<SysMenu> menus) {
     
   // 子节点parentId = 父节点ID
   return menus.stream().filter(m1 -> m.getId().equals(m1.getParentId()))
           .peek(m1 -> m1.setChildren(getChildren(m1, menus))).collect(Collectors.toList());
}

你可能感兴趣的:(vue,Mybatis)