基于Hutool TreeUtil 实现后端返回数据树形结构

本文涉及的产品
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
简介: 基于Hutool TreeUtil 实现后端返回数据树形结构

接下来模仿现实业务场景中,实现查询数据库得到数据,最后使用TreeUtil 处理数据,返回结果呈树形结构。

1:引入 Hutool 依赖

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.11</version>
</dependency>

2:数据库建表语句

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for department
-- ----------------------------
DROP TABLE IF EXISTS `department`;
CREATE TABLE `department`  (
  `id` int NOT NULL COMMENT '主键id 信息',
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '部门名称信息',
  `pid` int NOT NULL COMMENT '父节点id 信息',
  `status` int NULL DEFAULT NULL COMMENT '0:我呼死你 1:你被我打死了',
  `desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '对部门信息的描述',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of department
-- ----------------------------
INSERT INTO `department` VALUES (1, '北京阿里云有限公司', 0, 0, '我是大公司');
INSERT INTO `department` VALUES (2, '郑州云智能有限公司', 0, 1, '我是郑州公司');
INSERT INTO `department` VALUES (3, '开发部', 1, 1, '我是大公司下的部门');
INSERT INTO `department` VALUES (4, '测试部', 1, 1, '我是大公司下的部门');
INSERT INTO `department` VALUES (5, '云计算', 2, 1, '我是郑州公司下的部门');
INSERT INTO `department` VALUES (6, '大数据', 2, 1, '我是郑州公司下的部门');
INSERT INTO `department` VALUES (7, '夏天', 3, 1, '我是开发部的成员');
INSERT INTO `department` VALUES (8, '齐天大圣', 3, 1, '我是测试部的成员');
INSERT INTO `department` VALUES (9, '高俊俊', 5, 1, '我是云计算下面的专业');
INSERT INTO `department` VALUES (10, '张三三', 6, 1, '我是大数据的人');
SET FOREIGN_KEY_CHECKS = 1;

3:Result  结果类 以及 ResultCode

public class Result implements Serializable {
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    //状态码
    private Integer code;
    //响应消息
    private String msg;
    //响应数据
    private Object data;
    private Integer count;
    public Integer getCount() {
        return count;
    }
    public void setCount(Integer count) {
        this.count = count;
    }
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }
    public Result(ResultCode resultCode,Object data) {
        this.code=resultCode.getCode();
        this.msg=resultCode.getMsg();
        this.data=data;
    }
    public Result(Integer code,String msg,Object data) {
        this.code=code;
        this.msg=msg;
        this.data=data;
    }
}
//ResultCode  类
public enum ResultCode {
  SUCCESS(0,"成功"),
  ERROR(500,"操作失败"),
  private Integer code;
    private String msg;
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    ResultCode(Integer code,String msg){
        this.code=code;
        this.msg=msg;
    }
}

4:实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Department {
        private Integer id;
        private String name;
        private Integer pid;   //父id
        private Integer status; 
        private String desc;
        /**
         * 子目录列表
         */
        private List<Department> treeNode;
}

5:Controller 层

@RestController
@RequestMapping("/department")
public class DepartmentController {
    @Resource
    private DepartmentService departmentService;
    @PostMapping("treeDepartment")
    public Result treeDepartment(){
        List<Tree<String>> departmentAll = departmentService.findDepartmentAll();
        return new Result(ResultCode.SUCCESS,departmentAll);
    }
}

6:service 层

接口:

@Service
public interface DepartmentService {
    List<Tree<String>> findDepartmentAll();
}

实现类:

@Service
public class DepartmentSericeImpl implements DepartmentService {
    @Resource
    private DepartmentMapper departmentMapper;
    private static final String status = "status";
    private static final String desc = "desc";
    @Override
    public List<Tree<String>> findDepartmentAll() {
        List<Department> list = departmentMapper.findDepartmentAll();
        List<Department> list2 = CollUtil.newArrayList();
        //浅拷贝赋值
        list2.addAll(list);
        // rootId
        String pid = "0";
        //配置
        TreeNodeConfig nodeConfig = new TreeNodeConfig();
        // 自定义属性名 都要默认值的
        //设置ID对应的名称
        nodeConfig.setIdKey("id");
        // 最大递归深度 3级目录
        nodeConfig.setDeep(3);
//        入参
//        tree:  最终要返回的数据
//        node:  lists数据
//        返回
//        Tree<String>
//        Tree: 转换的实体 为数据源里的对象类型
//        String: ID类型
        //转换器
        List<Tree<String>> treeList = TreeUtil.build(list2, pid, nodeConfig,
                (node, tree) -> {
            //id
            tree.setId(node.getId().toString());
            //姓名
            tree.setName(node.getName());
            //获取父节点id
            tree.setParentId(node.getPid().toString());
            // 扩展的属性 ...
            tree.putExtra(status, node.getStatus());
            tree.putExtra(desc, node.getDesc());
        });
        return treeList;
    }
}

7:mapper 层

@Mapper
public interface DepartmentMapper {
    List<Department> findDepartmentAll();
}

mapper.xml文件:

<?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="com.example.demotest.mapper.DepartmentMapper">
    <select id="findDepartmentAll" resultType="com.example.demotest.pojo.Department">
        select * from department
    </select>
</mapper>

8:查询结果如下

{
    "code": 0,
    "msg": "成功",
    "data": [
        {
            "id": "1",
            "name": "北京阿里云有限公司",
            "parentId": "0",
            "status": 0,
            "desc": "我是大公司",
            "children": [
                {
                    "id": "3",
                    "name": "开发部",
                    "parentId": "1",
                    "status": 1,
                    "desc": "我是大公司下的部门",
                    "children": [
                        {
                            "id": "7",
                            "name": "夏天",
                            "parentId": "3",
                            "status": 1,
                            "desc": "我是开发部的成员",
                            "children": null
                        },
                        {
                            "id": "8",
                            "name": "齐天大圣",
                            "parentId": "3",
                            "status": 1,
                            "desc": "我是测试部的成员",
                            "children": null
                        }
                    ]
                },
                {
                    "id": "4",
                    "name": "测试部",
                    "parentId": "1",
                    "status": 1,
                    "desc": "我是大公司下的部门"
                }
            ]
        },
        {
            "id": "2",
            "name": "郑州云智能有限公司",
            "parentId": "0",
            "status": 1,
            "desc": "我是郑州公司",
            "children": [
                {
                    "id": "5",
                    "name": "云计算",
                    "parentId": "2",
                    "status": 1,
                    "desc": "我是郑州公司下的部门",
                    "children": [
                        {
                            "id": "9",
                            "name": "高俊俊",
                            "parentId": "5",
                            "status": 1,
                            "desc": "我是云计算下面的专业",
                            "children": null
                        }
                    ]
                },
                {
                    "id": "6",
                    "name": "大数据",
                    "parentId": "2",
                    "status": 1,
                    "desc": "我是郑州公司下的部门",
                    "children": [
                        {
                            "id": "10",
                            "name": "张三三",
                            "parentId": "6",
                            "status": 1,
                            "desc": "我是大数据的人",
                            "children": null
                        }
                    ]
                }
            ]
        }
    ],
    "count": null
}


相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
目录
相关文章
|
10天前
|
JavaScript API 开发工具
<大厂实战场景> ~ Flutter&鸿蒙next 解析后端返回的 HTML 数据详解
本文介绍了如何在 Flutter 中解析后端返回的 HTML 数据。首先解释了 HTML 解析的概念,然后详细介绍了使用 `http` 和 `html` 库的步骤,包括添加依赖、获取 HTML 数据、解析 HTML 内容和在 Flutter UI 中显示解析结果。通过具体的代码示例,展示了如何从 URL 获取 HTML 并提取特定信息,如链接列表。希望本文能帮助你在 Flutter 应用中更好地处理 HTML 数据。
93 1
|
1月前
|
JSON 前端开发 Java
震惊!图文并茂——Java后端如何响应不同格式的数据给前端(带源码)
文章介绍了Java后端如何使用Spring Boot框架响应不同格式的数据给前端,包括返回静态页面、数据、HTML代码片段、JSON对象、设置状态码和响应的Header。
121 1
震惊!图文并茂——Java后端如何响应不同格式的数据给前端(带源码)
|
10天前
|
JSON Dart 数据格式
<大厂实战场景> ~ flutter&鸿蒙next处理后端返回来的数据的转义问题
在 Flutter 应用开发中,处理后端返回的数据是常见任务,尤其涉及转义字符时。本文详细探讨了如何使用 Dart 的 `dart:convert` 库解析包含转义字符的 JSON 数据,并提供了示例代码和常见问题的解决方案,帮助开发者有效处理数据转义问题。
106 0
|
1月前
|
JavaScript 前端开发
vue3教程,如何手动获取后端数据(入门到精通3,新人必学篇)
本文提供了一个Vue 3教程,讲解了如何使用axios库手动从后端获取数据,包括安装axios、配置后端访问地址、编写路由地址、发起HTTP请求以及在组件中读取和打印响应数据的步骤。
252 0
vue3教程,如何手动获取后端数据(入门到精通3,新人必学篇)
|
2月前
|
JSON 数据格式
Blob格式转json格式,拿到后端返回的json数据
文章介绍了如何将后端返回的Blob格式数据转换为JSON格式,并处理文件下载和错误提示。
73 0
Blob格式转json格式,拿到后端返回的json数据
|
29天前
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
|
3月前
|
前端开发 JavaScript
这篇文章介绍了如何使用form表单结合Bootstrap格式将前端数据通过action属性提交到后端的servlet,包括前端表单的创建、数据的一级和二级验证,以及后端servlet的注解和参数获取。
这篇文章介绍了使用AJAX技术将前端页面中表单接收的多个参数快速便捷地传输到后端servlet的方法,并通过示例代码展示了前端JavaScript中的AJAX调用和后端servlet的接收处理。
这篇文章介绍了如何使用form表单结合Bootstrap格式将前端数据通过action属性提交到后端的servlet,包括前端表单的创建、数据的一级和二级验证,以及后端servlet的注解和参数获取。
|
3月前
|
小程序 JavaScript Java
微信小程序+SpringBoot接入后台服务,接口数据来自后端
这篇文章介绍了如何将微信小程序与SpringBoot后端服务进行数据交互,包括后端接口的编写、小程序获取接口数据的方法,以及数据在小程序中的展示。同时,还涉及到了使用Vue搭建后台管理系统,方便数据的查看和管理。
微信小程序+SpringBoot接入后台服务,接口数据来自后端
|
3月前
|
JavaScript 前端开发
Vue中传递自定义参数到后端、后端获取数据(使用Map接收参数)
这篇文章讲述了如何在Vue中通过Axios二次封装传递自定义参数到后端,并展示了后端如何使用Map接收这些参数,以及如何避免参数转换错误和统一接口设计的方法。
|
4月前
|
存储 开发框架 前端开发
基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理
基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理
下一篇
无影云桌面