Golang如何将树形结构的数据库数据转换为JSON

Golang如何将树形结构的数据库数据转换为JSON 如何解决这个问题。我有一个数据库树和一个类别表。

Db

我想检索数据以构建树形结构,并生成JSON文件。

{
    "status": 1,
    "message": "Success",
    "Data": [
        {
            "id": 1,
            "title": "Electronic",
            "child": {
                "id": 2,
                "title": "Computer"
                "child": {//*computer's child*//}
            },
        },

更多关于Golang如何将树形结构的数据库数据转换为JSON的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

你尝试过什么方法吗?它有效吗?

更多关于Golang如何将树形结构的数据库数据转换为JSON的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


func main() {
    fmt.Println("hello world")
}

我是Go语言的新手,目前只能从数据库中检索单行数据。 在SQL查询中我使用了JOIN。 请问有什么解决方案吗?

若要将数据编码为JSON,可以使用 encoding/json 包。官方博客上有一篇文章提供了介绍。

然后将数据读入等效的结构体或 map[string]interface{} 中,并使用前面提到的 encoding/json 包来获取 JSON 表示。

如果遇到任何问题,请展示你目前已有的代码,并说明你在哪里遇到了困难。

我知道这一点,但问题在于,如果我在数据库中有一个树形结构,并且想将其检索为JSON格式,该怎么办。

这是我在SQL中使用的查询:

SELECT t1.title AS lev1, t2.title as lev2, t3.title as lev3, t4.title as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent_id = t1.id_category
LEFT JOIN category AS t3 ON t3.parent_id = t2.id_category
LEFT JOIN category AS t4 ON t4.parent_id = t3.id_category
WHERE t1.title = 'ELECTRONIC';

查询结果: query

我希望像我在帖子中提到的那样,将其检索为JSON格式。

在Go中处理树形结构数据并转换为JSON,可以通过递归或迭代方式构建嵌套结构。以下是一个完整的解决方案:

package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"log"
)

// 数据库结构
type Category struct {
	ID       int    `json:"id"`
	Title    string `json:"title"`
	ParentID int    `json:"-"`
	Children []*Category `json:"children,omitempty"`
}

// 获取所有分类并构建树形结构
func buildCategoryTree(db *sql.DB) ([]*Category, error) {
	// 查询所有分类
	rows, err := db.Query("SELECT id, title, parent_id FROM categories")
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	// 创建映射表
	categoryMap := make(map[int]*Category)
	var categories []*Category

	// 读取所有分类
	for rows.Next() {
		var cat Category
		if err := rows.Scan(&cat.ID, &cat.Title, &cat.ParentID); err != nil {
			return nil, err
		}
		categoryMap[cat.ID] = &cat
		categories = append(categories, &cat)
	}

	// 构建树形结构
	var rootCategories []*Category
	for _, cat := range categories {
		if cat.ParentID == 0 {
			rootCategories = append(rootCategories, cat)
		} else {
			if parent, exists := categoryMap[cat.ParentID]; exists {
				parent.Children = append(parent.Children, cat)
			}
		}
	}

	return rootCategories, nil
}

// 响应结构
type Response struct {
	Status  int         `json:"status"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

func main() {
	// 连接数据库
	db, err := sql.Open("mysql", "user:password@/dbname")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// 构建树形结构
	tree, err := buildCategoryTree(db)
	if err != nil {
		log.Fatal(err)
	}

	// 创建响应
	response := Response{
		Status:  1,
		Message: "Success",
		Data:    tree,
	}

	// 转换为JSON
	jsonData, err := json.MarshalIndent(response, "", "  ")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(string(jsonData))
}

如果数据库表结构不同,可以使用这个通用版本:

// 通用树形构建函数
func BuildTreeFromRows(rows *sql.Rows, idField, parentField, titleField string) ([]map[string]interface{}, error) {
	var items []map[string]interface{}
	
	for rows.Next() {
		var id, parentID int
		var title string
		
		if err := rows.Scan(&id, &title, &parentID); err != nil {
			return nil, err
		}
		
		item := map[string]interface{}{
			"id":    id,
			"title": title,
		}
		
		if parentID == 0 {
			item["children"] = []map[string]interface{}{}
		}
		
		items = append(items, item)
	}
	
	// 构建嵌套结构
	return buildNestedTree(items, 0), nil
}

func buildNestedTree(items []map[string]interface{}, parentID int) []map[string]interface{} {
	var tree []map[string]interface{}
	
	for _, item := range items {
		if item["parent_id"] == parentID {
			children := buildNestedTree(items, item["id"].(int))
			if len(children) > 0 {
				item["children"] = children
			}
			tree = append(tree, item)
		}
	}
	
	return tree
}

对于大型数据集,可以使用迭代方式避免递归深度问题:

func BuildTreeIterative(db *sql.DB) ([]*Category, error) {
	rows, err := db.Query("SELECT id, title, parent_id FROM categories ORDER BY parent_id, id")
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	categoryMap := make(map[int]*Category)
	var rootCategories []*Category

	for rows.Next() {
		var cat Category
		if err := rows.Scan(&cat.ID, &cat.Title, &cat.ParentID); err != nil {
			return nil, err
		}

		categoryMap[cat.ID] = &cat

		if cat.ParentID == 0 {
			rootCategories = append(rootCategories, &cat)
		} else {
			if parent, exists := categoryMap[cat.ParentID]; exists {
				parent.Children = append(parent.Children, &cat)
			}
		}
	}

	return rootCategories, nil
}

输出结果将符合要求的JSON格式:

{
  "status": 1,
  "message": "Success",
  "data": [
    {
      "id": 1,
      "title": "Electronic",
      "children": [
        {
          "id": 2,
          "title": "Computer",
          "children": [
            {
              "id": 3,
              "title": "Laptop",
              "children": []
            }
          ]
        }
      ]
    }
  ]
}
回到顶部