JAVA返回树结构(宇宙第一详细教程)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: JAVA返回树结构(宇宙第一详细教程)

表结构



SQL结构和数据


DROP TABLE IF EXISTS `demo`;
CREATE TABLE `demo` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `pid` int(11) NOT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `demo` VALUES ('1', '0', 'A');
INSERT INTO `demo` VALUES ('2', '1', 'B');
INSERT INTO `demo` VALUES ('3', '1', 'C');
INSERT INTO `demo` VALUES ('4', '2', 'D');
INSERT INTO `demo` VALUES ('5', '2', 'E');
INSERT INTO `demo` VALUES ('6', '3', 'F');
INSERT INTO `demo` VALUES ('7', '3', 'G');


Pom文件


<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>

application.properties文件

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tree
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
TreeMapper
@Mapper
public interface TreeMapper {
    @Select("select * from demo")
    List<Tree> getAll();
}

对应数据库的Tree实体类


public class Tree {
    private Integer id;
    private Integer pid;
    private String name;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getPid() {
        return pid;
    }
    public void setPid(Integer pid) {
        this.pid = pid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Tree{" +
                "id=" + id +
                ", pid=" + pid +
                ", name='" + name + '\'' +
                '}';
    }
}


NewTree,定义返回给前段的树类型,根据业务不同自行修改(这里为了简单起见,只修改了id和pid的类型)


public class NewTree {
    private String id;
    private String pid;
    private String name;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getPid() {
        return pid;
    }
    public void setPid(String pid) {
        this.pid = pid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Tree{" +
                "id=" + id +
                ", pid=" + pid +
                ", name='" + name + '\'' +
                '}';
    }
}

MenuTreeUtil,递归构造树形结构


@Component
public class MenuTreeUtil {
    //已经被buildTree的list集合
    private List<NewTree> menuCommon;
    //返回给前端的NewTree List集合
    private List<Object> list = new ArrayList<Object>();
    public List<Object> menuList(List<NewTree> menu){
        this.menuCommon = menu;
        // 通过遍历menu,找到父节点为0的节点,它是顶级父节点
        // 然后调用menuChild,递归遍历所有子节点
        for (NewTree x : menu) {
            Map<String,Object> mapArr = new LinkedHashMap<String, Object>();
            if("0".equals(x.getPid())){
                mapArr.put("id", x.getId());
                mapArr.put("name", x.getName());
                mapArr.put("pid", x.getPid());
                //遍历开始
                mapArr.put("childList", menuChild(x.getId()));
                list.add(mapArr);
            }
        }
        return list;
    }
    private List<?> menuChild(String id){
        List<Object> lists = new ArrayList<Object>();
        //继续遍历menu
        for(NewTree a:menuCommon){
            Map<String,Object> childArray = new LinkedHashMap<String, Object>();
            //找到父ID等于父节点ID的子节点
            if(a.getPid().equals(id)){
                childArray.put("id", a.getId());
                childArray.put("name", a.getName());
                childArray.put("pid", a.getPid());
                //向下递归
                childArray.put("childList", menuChild(a.getId()));
                lists.add(childArray);
            }
        }
        return lists;
    }
}

TreeController


@Controller
public class TreeController {
    @Resource
    TreeMapper treeMapper;
    @Resource
    MenuTreeUtil menuTreeUtil;
    @RequestMapping(value = "/menuList",method = {RequestMethod.GET})
    @ResponseBody
    public String getTree() throws Exception {
        List<NewTree> list = buildTree(treeMapper.getAll());
        List<Object> menuList = menuTreeUtil.menuList(list);
        System.out.println(menuList);
        return "YES";
    }
    //将实体类,变成标准的树结构,即NewTree类型
    private List<NewTree> buildTree(List<Tree> list){
        List<NewTree> newTrees = new LinkedList<>();
        for(Tree tree:list){
            NewTree newTree = new NewTree();
            newTree.setId(String.valueOf(tree.getId()));
            newTree.setPid(String.valueOf(tree.getPid()));
            newTree.setName(tree.getName());
            newTrees.add(newTree);
        }
        return newTrees;
    }
}


启动项目,并在地址栏输入如下地址即可



结果展示(JSON在线解析JSON在线 | JSON解析格式化—SO JSON在线工具)


[{
  id = 1,
  name = A,
  pid = 0,
  childList = [{
  id = 2,
  name = B,
  pid = 1,
  childList = [{
    id = 4,
    name = D,
    pid = 2,
    childList = []
  }, {
    id = 5,
    name = E,
    pid = 2,
    childList = []
  }]
  }, {
  id = 3,
  name = C,
  pid = 1,
  childList = [{
    id = 6,
    name = F,
    pid = 3,
    childList = []
  }, {
    id = 7,
    name = G,
    pid = 3,
    childList = []
  }]
  }]
}]


参考 https://www.jb51.net/article/125076.htm


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2天前
|
Java 数据库连接 数据处理
探究Java异常处理【保姆级教程】
Java 异常处理是确保程序稳健运行的关键机制。它通过捕获和处理运行时错误,避免程序崩溃。Java 的异常体系以 `Throwable` 为基础,分为 `Error` 和 `Exception`。前者表示严重错误,后者可细分为受检和非受检异常。常见的异常处理方式包括 `try-catch-finally`、`throws` 和 `throw` 关键字。此外,还可以自定义异常类以满足特定需求。最佳实践包括捕获具体异常、合理使用 `finally` 块和谨慎抛出异常。掌握这些技巧能显著提升程序的健壮性和可靠性。
17 4
|
2天前
|
存储 移动开发 算法
【潜意识Java】Java基础教程:从零开始的学习之旅
本文介绍了 Java 编程语言的基础知识,涵盖从简介、程序结构到面向对象编程的核心概念。首先,Java 是一种高级、跨平台的面向对象语言,支持“一次编写,到处运行”。接着,文章详细讲解了 Java 程序的基本结构,包括包声明、导入语句、类声明和 main 方法。随后,深入探讨了基础语法,如数据类型、变量、控制结构、方法和数组。此外,还介绍了面向对象编程的关键概念,例如类与对象、继承和多态。最后,针对常见的编程错误提供了调试技巧,并总结了学习 Java 的重要性和方法。适合初学者逐步掌握 Java 编程。
12 1
|
28天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
1月前
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
148 26
|
2天前
|
前端开发 Java 开发工具
Git使用教程-将idea本地Java等文件配置到gitte上【保姆级教程】
本内容详细介绍了使用Git进行版本控制的全过程,涵盖从本地仓库创建到远程仓库配置,以及最终推送代码至远程仓库的步骤。
13 0
|
1月前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
1月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
2月前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
43 2
|
1月前
|
Java 数据库连接 编译器
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
67 0
|
2月前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)