mysql递归拼接树形JSON列表

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS AI 助手,专业版
简介: mysql递归拼接树形JSON列表

前言:在做java web项目时,前端控件例如国家-省-市-区-县等树形列表,常常需要多级树形json数据,例如:

   [
            {
                  "name": "商品目录",
                  "pid": "-1",
                  "id": "1",
                  "children": [
                    {
                      "name": "日用品",
                      "pid": "1",
                      "id": "11",
                      "children": [
                        {
                          "name": "洗发水",
                          "pid": "11",
                          "id": "111",
                          "children": [
                              {
                                  "name": "霸王",
                                  "pid": "111",
                                  "id": "1111",
                                  "children": []
                              }
                          ]
                        }
                      ]
                    },
                    {
                      "name": "食品",
                      "pid": "1",
                      "id": "12",
                      "children": []
                    }
                  ]
                }
              ]

整体思路分为两步,第一步获取目录及其所有子目录,获取后的列表形式如下:

[
            {"id":"1","pid":"-1","name":"商品目录"},
            {"id":"11","pid":"1","name":"日用品"},
            {"id":"12","pid":"1","name":"食品"},
            {"id":"111","pid":"11","name":"洗发水"},
            {"id":"1111","pid":"111","name":"霸王"}
        ]

第二步,利用递归思想拼装该数据,拼装方法的工具类如下:

package *.*.*;
import net.sf.json.JSONArray;
import java.util.ArrayList;
import java.util.List;
/**
 * 构造目录JSON树
 * Created by fukang on 2017/5/26 0026.
 */
public class TreeBuilder {
    List<Node> nodes = new ArrayList<>();
    public String buildTree(List<Node> nodes) {
        TreeBuilder treeBuilder = new TreeBuilder(nodes);
        return treeBuilder.buildJSONTree();
    }
    public TreeBuilder() {
    }
    public TreeBuilder(List<Node> nodes) {
        super();
        this.nodes = nodes;
    }
    // 构建JSON树形结构
    public String buildJSONTree() {
        List<Node> nodeTree = buildTree();
        JSONArray jsonArray = JSONArray.fromObject(nodeTree);
        return jsonArray.toString();
    }
    // 构建树形结构
    public List<Node> buildTree() {
        List<Node> treeNodes = new ArrayList<>();
        List<Node> rootNodes = getRootNodes();
        for (Node rootNode : rootNodes) {
            buildChildNodes(rootNode);
            treeNodes.add(rootNode);
        }
        return treeNodes;
    }
    // 递归子节点
    public void buildChildNodes(Node node) {
        List<Node> children = getChildNodes(node);
        if (!children.isEmpty()) {
            for (Node child : children) {
                buildChildNodes(child);
            }
            node.setChildren(children);
        }
    }
    // 获取父节点下所有的子节点
    public List<Node> getChildNodes(Node pnode) {
        List<Node> childNodes = new ArrayList<>();
        for (Node n : nodes) {
            if (pnode.getId().equals(n.getPid())) {
                childNodes.add(n);
            }
        }
        return childNodes;
    }
    // 判断是否为根节点
    public boolean rootNode(Node node) {
        boolean isRootNode = true;
        for (Node n : nodes) {
            if (node.getPid().equals(n.getId())) {
                isRootNode = false;
                break;
            }
        }
        return isRootNode;
    }
    // 获取集合中所有的根节点
    public List<Node> getRootNodes() {
        List<Node> rootNodes = new ArrayList<>();
        for (Node n : nodes) {
            if (rootNode(n)) {
                rootNodes.add(n);
            }
        }
        return rootNodes;
    }
    public static class Node {
        private String id;
        private String pid;
        private String name;
        private List<Node> children;
        public Node() {
        }
        public Node(String id, String pid, String name) {
            super();
            this.id = id;
            this.pid = pid;
            this.name = 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;
        }
        public List<Node> getChildren() {
            return children;
        }
        public void setChildren(List<Node> children) {
            this.children = children;
        }
    }
}

在Controller中的调用方法是:

 @RequestMapping("/bulidJsonTree")
    @ResponseBody
    public String buildJsonTree(HttpServletRequest request) {
        // 获取全部目录节点
        List<Node> nodes = iGoodsDirSvc.getAllDirList();
        // 拼装树形json字符串
        String json = new TreeBuilder().buildTree(nodes);
        return json;
    }

其中iGoodsDirSvc.getAllDirList()方法需要将取到的数据转为Node类型:

String hql = "select id as id,pId as pid,name as name from Directory";
Query query = factory.getCurrentSession().createQuery(hql)
.setResultTransformer(Transformers.aliasToBean(TreeBuilder.Node.class));
return query.list();

其次、我认为最简便转换JSON的方法是:

import com.alibaba.fastjson.JSON;
.........
    System.out.println(JSON.toJSONString(树数据集合));

见笑了,见笑了。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
9月前
|
关系型数据库 MySQL
MySQL字符串拼接方法全解析
本文介绍了四种常用的字符串处理函数及其用法。方法一:CONCAT,用于基础拼接,参数含NULL时返回NULL;方法二:CONCAT_WS,带分隔符拼接,自动忽略NULL值;方法三:GROUP_CONCAT,适用于分组拼接,支持去重、排序和自定义分隔符;方法四:算术运算符拼接,仅适用于数值类型,字符串会尝试转为数值处理。通过示例展示了各函数的特点与应用场景。
|
关系型数据库 MySQL 数据库
mysql 8.0 递归(例子分享)(sample database classicmodels _No.4)
本文介绍了如何在MySQL8.0中使用递归查询处理部门表和员工表的树形结构数据,包括查看文档、准备数据、递归处理以及提取层级信息。作者通过示例展示了WITHRECURSIVE语句的应用及其在数仓中的结构表示。
273 2
|
关系型数据库 MySQL
mysql & clinkhouse之查询 行拼接
mysql & clinkhouse之查询 行拼接
mysql & clinkhouse之查询 行拼接
|
JSON 关系型数据库 MySQL
MySQL JSON数据存储结构与操作
通过本文的介绍,我们了解了MySQL中JSON数据类型的基本操作、常用JSON函数、以及如何通过索引和优化来提高查询性能。JSON数据类型为存储和操作结构化数据提供了灵活性和便利性,在现代数据库应用中具有广泛的应用前景。希望本文对您在MySQL中使用JSON数据类型有所帮助。
1397 0
|
存储 JSON 关系型数据库
MySQL与JSON的邂逅:开启大数据分析新纪元
MySQL与JSON的邂逅:开启大数据分析新纪元
|
存储 算法 关系型数据库
探索MySQL递归查询,优雅的给树结构分页!
总结起来,对于MySQL中的树结构数据,递归查询结合预排序遍历树算法可以实现优雅的分页,但需要注意性能优化和数据更新的问题。这项技术提供了一种高效处理层级数据的工具,使得开发者可以在复杂的数据结构下实现直观和可靠的数据查询。
929 1
|
关系型数据库 MySQL
mysql使用 CONCAT(字段,字段) 函数拼接
mysql使用 CONCAT(字段,字段) 函数拼接
218 2
|
JSON 关系型数据库 MySQL
MySQL中GROUP_CONCAT与JSON_OBJECT、GROUP BY的巧妙结合:打造高效JSON数组汇总
MySQL中GROUP_CONCAT与JSON_OBJECT、GROUP BY的巧妙结合:打造高效JSON数组汇总
722 1
|
JSON 关系型数据库 MySQL
理解和利用MySQL中的JSON功能
理解和利用MySQL中的JSON功能
598 2
|
JSON 关系型数据库 MySQL
实时计算 Flink版产品使用问题之在使用CDAS语法同步MySQL数据到Hologres时,如果开启了字段类型宽容模式,MySQL中的JSON类型会被转换为什么
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。

推荐镜像

更多