Java develops tree structure data encapsulation!


The source needs to encapsulate the data as follows:

source data

controller interface:

@RequestMapping("/UserTreeInfo")
    public RespBody getUserTreeInfo(Long userId) {
    
    
        List<MenuTreeVo> userInfo = userInfoServiceimpl.getUserTreeInfo(userId);
        if (userInfo != null && userInfo.size() > 0) {
    
    
            return new RespBody(200,userInfo,"查询成功");
        }
        return new RespBody(501,null,"查询失败");
    }

Service layer encapsulation tree structure:

package com.ekgc.qy.Service.impl;

import com.ekgc.qy.Service.UserInfoService;
import com.ekgc.qy.dao.UserInfoDao;
import com.ekgc.qy.pojo.vo.MenuTreeVo;
import jakarta.annotation.Resource;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Magic
 * @version 1.0
 */
@Service
public class UserInfoServiceimpl implements UserInfoService {
    
    
    @Resource
    private UserInfoDao userInfoDao;

    @Override
    public List<MenuTreeVo> findGetInfoByUserId(Long userId) {
    
    
        return userInfoDao.findGetInfoByUserId(userId);
    }

    /**
     * 查询树结构菜单
     * @return 返回树结构菜单
     */
    @Override
    public List<MenuTreeVo> getUserTreeInfo(Long userId) {
    
    
        //查出所有菜单和目录
        List<MenuTreeVo> userTreeInfo = userInfoDao.getUserTreeInfo(userId);
        // 先过滤出所有的父菜单目录
        // 方法一:已知所有目录的parentId为0
//        List<MenuTreeVo> muLuList = userTreeInfo.stream()
//                .filter(item -> item.getParentId() == 0)
//                .toList();
        // 方法二:建立映射关系id->MenuTreeVo对象
        HashMap<Long, MenuTreeVo> itemMap = new HashMap<>();
        for (MenuTreeVo itemDict : userTreeInfo) {
    
    
            itemMap.put(itemDict.getId(), itemDict);
        }

        //设置去重的项目muLu
        Set<MenuTreeVo> muLu = new HashSet<>();
        for (MenuTreeVo item : userTreeInfo) {
    
    
            // 获取父节点
            // 传递表中每一个项目parentId,itemMap如果能获取到值说明这是一个目录
            MenuTreeVo parentItem = itemMap.get(item.getParentId());
            if (parentItem != null) {
    
    
                muLu.add(parentItem);
            }
        }
        ArrayList<MenuTreeVo> muLuList = new ArrayList<>(muLu);
        return buildTrees(muLuList,userTreeInfo);
    }

	    /**
     * 封装树菜单
     * @param data 顶层父节点 目录
     * @param menus 所有菜单
     * @return 返回封装树菜单
     */
    private ArrayList<MenuTreeVo> buildTrees(List<MenuTreeVo> data, List<MenuTreeVo> menus) {
    
    
        // 存储树结构的菜单树
        ArrayList<MenuTreeVo> trees = new ArrayList<>();
        // 封装树结构菜单数据
        for (MenuTreeVo md : data) {
    
    
            // 封装的MenuTreeVo树结构对象
            MenuTreeVo ml = new MenuTreeVo();
            // 根据属性名 将数据复制到另一个对象
            // 实现MenuDto到MenuTreeVo的转换
            try {
    
    
                BeanUtils.copyProperties(ml, md);//前一个是目标对象,后一个是源对象
            } catch (IllegalAccessException e) {
    
    
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
    
    
                throw new RuntimeException(e);
            }


            //遍历目录和菜单找出子菜单并封装子菜单
            List<MenuTreeVo> childs = new ArrayList<>();
            menus.forEach(m ->{
    
    
                if (m.getParentId() != null){
    
    
                    if (m.getParentId().equals(md.getId())){
    
    
                        childs.add(m);
                    }
                }
            });
            //设置递归深度且有子菜单
            // 菜单级别是1有子菜单 执行递归
            if (!childs.isEmpty() && ml.getMenuType() < 2) {
    
    
                // 设置父节点有子菜单的childMenus属性
                ml.setChildMenus(buildTrees(childs, menus));
            }
            //添加封装的菜单
            trees.add(ml);
        }
        return trees;
    }
}

Dao interface:

package com.ekgc.qy.dao;

import com.ekgc.qy.pojo.vo.MenuTreeVo;

import java.util.List;

/**
 * @author Magic
 * @version 1.0
 */
public interface UserInfoDao {
    
    
    List<MenuTreeVo> findGetInfoByUserId(Long userId);

    List<MenuTreeVo> getUserTreeInfo(Long userId);

}

Dao layer Mapper:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- mapper是映射文件的根标签 namespace属性 指定mapper映射对应的mapper接口是谁 -->
<mapper namespace="com.ekgc.qy.dao.UserInfoDao">
    <!--    id:重写的方法;
resultType:返回值类型。pojo实体类
resultMap 对应返回值类型需要手动指定
parameterType:对应方法参数类型
-->
    <!--    列表一对多嵌套-->
    <resultMap id="roleMenus" type="MenuTreeVo">
        <id property="id" column="id"/>
        <result property="menuName" column="menu_name"/>
        <result property="permissions" column="permissions"/>
        <collection property="childMenus" ofType="MenuTreeVo" javaType="java.util.ArrayList">
            <id property="id" column="childId"/>
            <result property="menuName" column="menuName"/>
            <result property="menuUrl" column="menuUrl"/>
            <result property="permissions" column="auth"/>
            <result property="path" column="path"/>
            <result property="parentId" column="parent_id"/>
        </collection>
    </resultMap>

    <!--    colection1对多查询-->
    <select id="findGetInfoByUserId" resultMap="roleMenus">
        SELECT ml.id,ml.menu_name,ml.permissions,
               sy.id AS childId,sy.menu_name AS menuName,sy.menu_url AS menuUrl,sy.permissions AS auth,sy.path,sy.parent_id FROM sys_menu sy,
               (SELECT sm.id,menu_name,permissions FROM sys_menu sm
                LEFT JOIN sys_role_menu srm ON sm.id = srm.menu_id
                LEFT JOIN sys_role sr ON srm.role_id = sr.id
                LEFT JOIN sys_user su ON su.user_type = sr.id
                WHERE su.id = #{userId}) AS ml WHERE ml.id = sy.parent_id
    </select>

    <select id="getUserTreeInfo" resultType="com.ekgc.qy.pojo.vo.MenuTreeVo">
        SELECT sm.id,menu_name,menu_url,path,permissions,parent_id FROM sys_menu sm
        LEFT JOIN sys_role_menu srm ON sm.id = srm.menu_id
        LEFT JOIN sys_role sr ON srm.role_id = sr.id
        LEFT JOIN sys_user su ON su.user_type = sr.id
        WHERE su.id = #{userId}
    </select>
</mapper>

Mapping entity classes:

实体类只要有sql查询到的字段(id,menu_name,menu_url,path,permissions,parent_id)有就可以映射,不能缺少某个字段否则映射不了!

package com.ekgc.qy.pojo.vo;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.ArrayList;

/**
 * @author Magic
 * @version 1.0
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class MenuTreeVo {
    
    
    private Long id;
    private String menuName;
    private String menuUrl;
    private String permissions;
    private String path;
    private Long parentId;
    private ArrayList<MenuTreeVo> childMenus;
}

Response result:

{
    
    
    "status": 200,
    "data": [
        {
    
    
            "id": 4,
            "menuName": "用户管理",
            "menuUrl": "",
            "permissions": "system:user",
            "path": "",
            "parentId": 0,
            "childMenus": [
                {
    
    
                    "id": 5,
                    "menuName": "用户列表",
                    "menuUrl": "../components/system/UserManger/select_update_delete",
                    "permissions": "system:user:list",
                    "path": "/s_u_d",
                    "parentId": 4,
                    "childMenus": null
                },
                {
    
    
                    "id": 6,
                    "menuName": "添加用户",
                    "menuUrl": "../components/system/UserManger/addUserForm",
                    "permissions": "system:user:add",
                    "path": "/addUser",
                    "parentId": 4,
                    "childMenus": null
                }
            ]
        },
        {
    
    
            "id": 13,
            "menuName": "系统管理",
            "menuUrl": null,
            "permissions": "system:diagnosis",
            "path": null,
            "parentId": 0,
            "childMenus": [
                {
    
    
                    "id": 14,
                    "menuName": "出诊管理",
                    "menuUrl": "../components/system/MenZhenManger/chuZhenManger",
                    "permissions": "system:diagnosis:list",
                    "path": "/chuZhen",
                    "parentId": 13,
                    "childMenus": null
                },
                {
    
    
                    "id": 15,
                    "menuName": "新增出诊",
                    "menuUrl": "../components/system/MenZhenManger/addChuZhenForm",
                    "permissions": "system:diagnosis:add",
                    "path": "/addChuZhen",
                    "parentId": 13,
                    "childMenus": null
                }
            ]
        }
    ],
    "msg": "查询成功"
}

Guess you like

Origin blog.csdn.net/qq_58647634/article/details/133920256