golang create tree from mysql

golang web develop always using tree menu in our project.then that can be Reference resources.this article teach you how to get tree menu in web project.

1.show table of menu in mysql database

```
mysql> desc menu;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(50) | YES  |     | NULL    |       |
| pid   | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

```
mysql> select * from menu;
+------+------+------+
| id   | name | pid  |
+------+------+------+
|    1 | aa   |    0 |
|    2 | bb   |    1 |
|    3 | cc   |    1 |
|    4 | dd   |    2 |
|    5 | ee   |    3 |
|    6 | ee   |    4 |
+------+------+------+
6 rows in set (0.00 sec)
```

2.base operation in golang,that include tree files thats call db.go/menu.go/main.go

db.go

package model

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)

var (
    dbURL = "root:root@tcp(127.0.0.1:3306)/test?charset=utf8"
)

func Tx(v_sql string, args ...interface{}) (*sql.Rows, error) {
    db, err := sql.Open("mysql", dbURL)
    defer db.Close()
    stmt, err := db.Prepare(v_sql)
    if err != nil {
        fmt.Println("Tx err:", err)
        return nil, err
    }
    return stmt.Query(args...)
}
menu.go

package model

import (
    "database/sql"
    "fmt"
)

const (
    QuerySQL = "select id,name,pid from menu where pid =?"
)

type Menu struct {
    CurId    int64   `json:"curid"`
    Name     string  `json:"name"`
    ParentId int64   `json:"parentid"`
    Child    []*Menu `json:"child,omitempty"`
}

func MenuAppend(m *Menu) {
    fmt.Println(QuerySQL)
    child, err := MenuInit(QuerySQL, m.CurId)
    if err != nil {
        fmt.Println("MenuAppend err:", err)
        return
    }
    m.Child = child
    for _, v := range m.Child {
        MenuAppend(v)
    }
}
func LoadMenu() (*Menu, error) {
    ms, err := MenuInit(QuerySQL, 0)
    if err != nil {
        fmt.Println("LoadMenu err:", err)
        return nil, err
    }
    root := ms[0]
    MenuAppend(root)
    return root, nil
}
func MenuInit(sql0 string, id int64) ([]*Menu, error) {
    rows, err := Tx(sql0, id)
    if err != nil {
        fmt.Println("MeneInit err:", err)
        return nil, err
    }
    ms := make([]*Menu, 0)
    for rows.Next() {
        m := &Menu{}
        var id sql.NullInt64
        var name sql.NullString
        var pid sql.NullInt64
        if err = rows.Scan(&id, &name, &pid); err != nil {
            fmt.Println("MenuInit error:", err)
            return nil, err
        }
        if id.Valid {
            m.CurId = id.Int64
        }
        if name.Valid {
            m.Name = name.String
        }
        if pid.Valid {
            m.ParentId = pid.Int64
        }
        ms = append(ms, m)
    }
    fmt.Println("current data:", ms)
    return ms, nil
}
main.go

package main

import (
    "encoding/json"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "model"
)

func main() {
    root, err := model.LoadMenu()
    if err != nil {
        fmt.Println("err:", err)
    }
    b, err := json.Marshal(root)
    fmt.Println(string(b))
}

3.run and get tree data from json

{
  "curid": 1, 
  "name": "aa", 
  "parentid": 0, 
  "child": [
    {
      "curid": 2, 
      "name": "bb", 
      "parentid": 1, 
      "child": [
        {
          "curid": 4, 
          "name": "dd", 
          "parentid": 2, 
          "child": [
            {
              "curid": 6, 
              "name": "ee", 
              "parentid": 4
            }
          ]
        }
      ]
    }, 
    {
      "curid": 3, 
      "name": "cc", 
      "parentid": 1, 
      "child": [
        {
          "curid": 5, 
          "name": "ee", 
          "parentid": 3
        }
      ]
    }
  ]
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Astronomygonova - A wrapper for libnova -- Celestial Mech...
    JumboWu阅读 12,986评论 0 41
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 32,633评论 18 399
  • 2017/04/22 (44) 周六 晴 #to do list# 1、Time 1篇文章总结 2、TEM8 1 ...
    征人随说阅读 1,108评论 0 0
  • 这么说吧!我的室友简称世友不为过吧!世友指非常罕有的意思,同时我们也是同学。共同住在一个三房二厅一厨二卫一阳台的房...
    victory527阅读 3,017评论 1 2
  • 了解measure过程之前,要先了解一下MeasureSpec和LayoutParams的概念,因为View的大小...
    深情不及酒伴阅读 2,895评论 0 1

友情链接更多精彩内容