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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 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


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
3月前
|
Java 开发者 UED
【实战宝典】Java异常处理大师级教程:throws关键字,让异常声明成为你的专属标签!
【实战宝典】Java异常处理大师级教程:throws关键字,让异常声明成为你的专属标签!
60 3
|
17天前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
17天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
17天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
|
26天前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
61 2
|
1月前
|
Java 数据库连接 编译器
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
|
1月前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
本系列教程笔记详细讲解了Kotlin语法,适合希望深入了解Kotlin的开发者。对于需要快速学习Kotlin的小伙伴,推荐查看“简洁”系列教程。本篇笔记重点介绍了Kotlin与Java混编的技巧,包括代码转换、类调用、ProGuard问题、Android库开发建议以及相互调用时的注意事项。
24 3
|
1月前
|
安全 Java API
🌟探索Java宇宙:深入理解Java技术体系与JVM的奥秘
本文深入探讨了Java技术体系的全貌,从Java语言的概述到其优点,再到Java技术体系的构成,以及JVM的角色。旨在帮助Java开发者全面了解Java生态,提升对Java技术的认知,从而在编程实践中更好地发挥Java的优势。关键词:Java, JVM, 技术体系, 编程语言, 跨平台, 内存管理。
35 2
|
1月前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
22 3