Java开发树结构数据封装!

news2024/10/12 11:19:47

目录

    • 源数据如下
    • controller接口:
    • service层封装:
    • Dao接口:
    • Dao层Mapper:
    • 映射实体类:


源数据如下

源数据

controller接口:

@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层封装:

package com.ekgc.qy.Service.impl;

import com.ekgc.qy.Service.UserInfoService;
import com.ekgc.qy.dao.UserInfoDao;
import com.ekgc.qy.pojo.dto.MenuDto;
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<MenuDto> userTreeInfo = userInfoDao.getUserTreeInfo(userId);
        // 先过滤出所有的父菜单目录
        List<MenuDto> mulu = userTreeInfo
                .stream()
                .filter(ml -> ml.getParentId() == 0).toList();
        return buildTrees(mulu,userTreeInfo);
    }

    private ArrayList<MenuTreeVo> buildTrees(List<MenuDto> data, List<MenuDto> menus) {
        // 存储树结构的菜单树
        ArrayList<MenuTreeVo> trees = new ArrayList<>();
        // 封装树结构菜单数据
        data.forEach(md -> {
            // 封装的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<MenuDto> childs = new ArrayList<>();
            menus.forEach(m ->{
                if (m.getParentId() != null){
                    if (m.getParentId().equals(md.getId())){
                        childs.add(m);
                    }
                }
            });
            // 没有子菜单 不继续执行递归
            if (!childs.isEmpty()) {
                ml.setChildMenus(buildTrees(childs, menus));
            }
            trees.add(ml);
        });
        return trees;
    }
}

Dao接口:

package com.ekgc.qy.dao;

import com.ekgc.qy.pojo.dto.MenuDto;
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<MenuDto> getUserTreeInfo(Long userId);

}

Dao层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="MenuDto" 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.dto.MenuDto">
        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} AND menu_name like concat("%",#{menuName},"%")
    </select>
</mapper>

映射实体类:

实体类只要有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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1108868.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何使用BERT生成单词嵌入?

阿比贾特萨拉里 一、说明 BERT&#xff0c;或来自变形金刚&#xff08;Transformer&#xff09;的双向编码器表示&#xff0c;是由谷歌开发的强大语言模型。它已广泛用于自然语言处理任务&#xff0c;例如情感分析、文本分类和命名实体识别。BERT的主要特征之一是它能够生成单词…

python中不可变类型和可变类型

不可变类型&#xff1a;修改之后内存存储地址不会发生改变 可变类型&#xff1a;修改之后内存存储地址发生改变 set

chromium线程模型(2)-线程池实现

通过chromium 官方文档&#xff0c;线程和任务一节我们可以知道 &#xff0c;chromium有两类线程&#xff0c;一类是普通线程&#xff0c;最典型的就是io线程和ui线程。 另一类是 线程池线程。 今天我们先分析线程池的实现&#xff08;基于版本 117.0.5847.0&#xff08;开发者…

python小游戏:飞机射击游戏代码

创建一个完整的飞行游戏涉及到许多方面&#xff0c;包括图形设计、游戏物理引擎和用户输入处理等。在这里&#xff0c;我将提供一个简单的基础框架&#xff0c;你可以在其基础上进一步扩展和完善游戏。 在这个示例中&#xff0c;我们将使用Pygame库来创建一个基本的飞行游戏。…

端点管理软件

在各公司管理中心&#xff0c;端点管理软件发挥着举足轻重的作用&#xff0c;那么&#xff0c;究竟什么是端点管理软件&#xff1f;它的意义和具体应用场景又是什么&#xff1f; 端点管理软件是什么 端点管理软件是一种计算机安全管理工具&#xff0c;负责对网络中的终端设备进…

OceanBase自动安装部署演示环境demo

OceanBase自动安装部署 前提条件 官方给出硬件条件需要满足以下要求 本文操作系统为&#xff1a;Red Hat Enterprise Linux 8 64 位 下载链接&#xff1a;https://pan.baidu.com/s/1rZ39xJFhk0HdmC4wEJcxvg 提取码&#xff1a;c01x 下载并安装 all-in-one 安装包 执行如下…

RK3588开发笔记(二):基于方案商提供sdk搭建引入mpp和sdk的宿主机交叉编译Qt5.12.10环境

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/133915614 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

linux 防火墙介绍以及iptables的使用

背景介绍 在前几天&#xff0c;于工发现我们内部的150服务器7554端口被外网访问了。该应用提供着内部的摄像头资源。为了避免被入侵&#xff0c;于是我添加了一些iptables规则&#xff0c;防止外网的访问。 解决方式 解决方式有两种&#xff1a; 关闭公司公网路由器对150服务…

跑得“快”还要走得“稳”,看头部车企数字化实践怎么做

立足于人工智能、大数据、云计算等各种新技术变革的交汇点&#xff0c;无论是造车新势力还是传统车企&#xff0c;都在积极构建全链条、全流程数字化生态圈。在看得见的产品智能化、功能自动化之下&#xff0c;车企自身的数字化能力建设&#xff0c;则成为影响竞争格局的一条秘…

linux uboot kenerl filesystem关系

每次烧写都是uboot&#xff0c;image&#xff0c;roots&#xff0c;为什么不整一套&#xff0c;为什么分开 什么是uboot 什么是内核&#xff0c;三者为什么分开 如果你上网去搜一下&#xff0c;你会发现这样的答案 另注&#xff1a;本文含有大量的错误和意测成份&#xff0c…

【脉冲通信】用于空间应用的飞秒脉冲通信的符号误码率模型研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

超声波清洗机有没有平价又好用的推荐、平价好用超声波清洗机总结

超声波清洗机以其高效、环保、节能等优点在日常生活中得到了广泛应用。无论是在珠宝首饰、眼镜等小物品的清洁方面&#xff0c;还是在医疗领域的清洁消毒方面&#xff0c;超声波清洗机都发挥着不可替代的作用。在购买超声波清洗机时&#xff0c;需要根据自己的具体需求选择合适…

“创新启变 聚焦增长”极狐(GitLab)媒体沟通会,共话智能时代软件开发新生态

10 月 18 日 北京 昨日&#xff0c;全球领先 AI 赋能 DevSecOps 一体化平台极狐(GitLab) 在北京举办了主题为“创新启变 聚焦增长”的媒体沟通会。极狐(GitLab) CEO 柳钢就“中国企业数字化转型、软件研发、技术自主可控等热点问题&#xff0c;以及 AI 大模型时代下&#xff0c…

逐字稿 | 2 MoCo 论文逐段精读【论文精读】

bryanyzhu的个人空间-bryanyzhu个人主页-哔哩哔哩视频 评价 今天我们一起来读一下 MOCO 这篇论文。 MOCO 是 CVPR 2020 的最佳论文提名&#xff0c;算是视觉领域里使用对比学习的一个里程碑式的工作。而对比学习作为从 19 年开始一直到现在视觉领域乃至整个机器学习领域里最炙…

数据可视化素材分享 | 数十图表、无数模板

很多人在后台求分享报表、源代码&#xff0c;其实何必这么麻烦&#xff0c;在奥威BI数据可视化平台上点击即可获得大量的可视化素材&#xff0c;如数十种可视化图表&#xff0c;适用于不同分析场景&#xff1b;又如大量不同主题的BI数据可视化报表模板&#xff0c;套用后替换数…

JAVA性能优化:n个小细节让你提升java代码的运行效率

目录 1、尽量指定类、方法的final修饰符 2、尽量重用对象 3、尽可能使用局部变量 4、及时关闭流 5、尽量减少对变量的重复计算 6、尽量采用懒加载的策略&#xff0c;即在需要的时候才创建 7、慎用异常 8、不要在循环中使用try…catch…&#xff0c;应该把其放在最外层 …

神经网络量化----为了部署而特别设计

引言&#xff1a;一般神经网络量化有两个目的&#xff1a; 为了加速&#xff0c;在某些平台上浮点数计算比较耗费时间&#xff0c;替换为整形可以加快运算为了部署&#xff0c;某些平台上只支持整形运算&#xff0c;比如在芯片中 如果是第1个目的&#xff0c;则使用常规的量化手…

在线课堂分销商城小程序源码系统 带完整搭建教程

大家好啊&#xff0c;今天来给大家分享一个在线课堂分销商城小程序源码系统&#xff0c;一起来看看吧。以下是部分功能实现的核心代码&#xff1a; 系统特色功能一览&#xff1a; 商品模块。包括实物商品、虚拟商品和电子卡密等&#xff0c;每种商品可以设置对应的商品分类。同…

购药不烦恼:线上购药小程序的快捷方式

在这个数字化时代&#xff0c;线上购药小程序的快捷方式正在改变着我们购药的方式。本文将介绍如何通过使用Python和Flask框架创建一个简单的线上购药小程序的原型&#xff0c;为用户提供购药的便利和快捷体验。 安装和设置 首先&#xff0c;确保你已经安装了Python和Flask。…

MATLAB中ss2tf函数用法

目录 语法 说明 示例 质点-弹簧系统 双体振荡器 ss2tf函数的功能是将状态空间表示形式转换为传递函数。 语法 [b,a] ss2tf(A,B,C,D) [b,a] ss2tf(A,B,C,D,ni) 说明 [b,a] ss2tf(A,B,C,D) 将方程组的状态空间表示形式转换为等同的传递函数。ss2tf 返回连续时间方程组…