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

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 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


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
18天前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(二十九)-java+ selenium自动化测试- Actions的相关操作上篇(详解教程)
【4月更文挑战第21天】本文介绍了Selenium中处理特殊测试场景的方法,如鼠标悬停。Selenium的Actions类提供了鼠标悬停功能,用于模拟用户在网页元素上的悬停行为。文中通过实例展示了如何使用Actions悬停并展开下拉菜单,以及在搜索时选择自动补全的字段。代码示例包括了打开百度首页,悬停在“更多”元素上显示下拉菜单并点击“音乐”,以及在搜索框输入关键词并自动补全的过程。
38 0
|
3天前
|
Web App开发 JavaScript 前端开发
《手把手教你》系列技巧篇(三十九)-java+ selenium自动化测试-JavaScript的调用执行-上篇(详解教程)
【5月更文挑战第3天】本文介绍了如何在Web自动化测试中使用JavaScript执行器(JavascriptExecutor)来完成Selenium API无法处理的任务。首先,需要将WebDriver转换为JavascriptExecutor对象,然后通过executeScript方法执行JavaScript代码。示例用法包括设置JS代码字符串并调用executeScript。文章提供了两个实战场景:一是当时间插件限制输入时,用JS去除元素的readonly属性;二是处理需滚动才能显示的元素,利用JS滚动页面。还给出了一个滚动到底部的代码示例,并提供了详细步骤和解释。
27 10
|
11天前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(三十六)-java+ selenium自动化测试-单选和多选按钮操作-番外篇(详解教程)
【4月更文挑战第28天】本文简要介绍了自动化测试的实战应用,通过一个在线问卷调查(&lt;https://www.sojump.com/m/2792226.aspx/&gt;)为例,展示了如何遍历并点击问卷中的选项。测试思路包括找到单选和多选按钮的共性以定位元素,然后使用for循环进行点击操作。代码设计方面,提供了Java+Selenium的示例代码,通过WebDriver实现自动答题。运行代码后,可以看到控制台输出和浏览器的相应动作。文章最后做了简单的小结,强调了本次实践是对之前单选多选操作的巩固。
23 0
|
1天前
|
前端开发 测试技术 Python
《手把手教你》系列技巧篇(四十一)-java+ selenium自动化测试 - 处理iframe -上篇(详解教程)
【5月更文挑战第5天】本文介绍了HTML中的`iframe`标签,它用于在网页中嵌套其他网页。`iframe`常用于加载外部内容或网站的某个部分,以实现页面美观。文章还讲述了使用Selenium自动化测试时如何处理`iframe`,通过`switchTo().frame()`方法进入`iframe`,完成相应操作,然后使用`switchTo().defaultContent()`返回主窗口。此外,文章提供了一个包含`iframe`的HTML代码示例,并给出了一个简单的自动化测试代码实战,演示了如何在`iframe`中输入文本。
12 3
|
2天前
|
JavaScript 前端开发 Java
《手把手教你》系列技巧篇(四十)-java+ selenium自动化测试-JavaScript的调用执行-下篇(详解教程)
【5月更文挑战第4天】本文介绍了如何使用JavaScriptExecutor在自动化测试中实现元素高亮显示。通过创建并执行JS代码,可以改变元素的样式,例如设置背景色和边框,以突出显示被操作的元素。文中提供了一个Java示例,展示了如何在Selenium中使用此方法,并附有代码截图和运行效果展示。该技术有助于跟踪和理解测试过程中的元素交互。
7 0
|
4天前
|
JavaScript 前端开发 测试技术
《手把手教你》系列技巧篇(三十八)-java+ selenium自动化测试-日历时间控件-下篇(详解教程)
【5月更文挑战第2天】在自动化测试过程中,经常会遇到处理日期控件的点击问题。宏哥之前分享过一种方法,但如果输入框是`readonly`属性,这种方法就无法奏效了。不过,通过修改元素属性,依然可以实现自动化填写日期。首先,定位到日期输入框并移除`readonly`属性,然后使用`sendKeys`方法输入日期。这样,即使输入框设置了`readonly`,也能成功处理日期控件。
23 1
|
5天前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(三十七)-java+ selenium自动化测试-日历时间控件-上篇(详解教程)
【5月更文挑战第1天】该文介绍了使用Selenium自动化测试网页日历控件的方法。首先,文章提到在某些Web应用中,日历控件常用于选择日期并筛选数据。接着,它提供了两个实现思路:一是将日历视为文本输入框,直接输入日期;二是模拟用户交互,逐步选择日期。文中给出了JQueryUI网站的一个示例,并展示了对应的Java代码实现,包括点击日历、选择日期等操作。
21 0
|
11天前
|
Java 测试技术 项目管理
Java基础教程(22)-构建工具Maven的基本使用
【4月更文挑战第22天】Maven是Java项目管理及构建工具,简化构建、测试、打包和部署等任务。遵循约定优于配置原则,核心是`pom.xml`配置文件,用于管理依赖和项目信息。安装涉及下载、解压、配置环境变量。在IDEA中使用Maven创建项目,通过`pom.xml`添加依赖和管理版本。常用命令包括`clean`、`compile`、`test`、`package`、`install`和`deploy`。IDEA支持直接执行这些命令。
|
11天前
|
NoSQL Java 关系型数据库
Java基础教程(21)-Java连接MongoDB
【4月更文挑战第21天】MongoDB是开源的NoSQL数据库,强调高性能和灵活性。Java应用通过MongoDB Java驱动与之交互,涉及MongoClient、MongoDatabase、MongoCollection和Document等组件。连接MongoDB的步骤包括:配置连接字符串、创建MongoClient、选择数据库和集合。伪代码示例展示了如何建立连接、插入和查询数据。
|
12天前
|
存储 前端开发 测试技术
《手把手教你》系列技巧篇(三十五)-java+ selenium自动化测试-单选和多选按钮操作-下篇(详解教程)
【4月更文挑战第27天】本文介绍了使用Java+Selenium进行Web自动化测试时,如何遍历和操作多选按钮的方法。文章分为两个部分,首先是一个本地HTML页面的示例,展示了多选按钮的HTML代码和页面效果,并详细解释了遍历多选按钮的思路:找到所有多选按钮的共同点,通过定位这些元素并放入list容器中,然后使用for循环遍历并操作。 第二部分介绍了在JQueryUI网站上的实战,给出了被测网址,展示了代码设计,同样使用了findElements()方法获取所有多选按钮并存储到list中,然后遍历并进行点击操作。最后,文章对整个过程进行了小结,并推荐了作者的其他自动化测试教程资源。
19 0