建一个简单的表,结构如下,解释一下这三个字段的作用
- id:每个record的唯一id
- parentId:父节点的id,如果父节点是一级节点就为0
- value:node的值
字段数据结构
type Node struct {
Id string
ParentId string
Value string
}
func (*Node) TableName() string {
return "node"
}
受用Node接受sql返回的数据
连接mysql
type Conn struct {
db *gorm.DB
}
func (c *Conn) SelectNode(parentId string) *[]Node{
var list []Node
c.db.Raw("SELECT * FROM node WHERE parent_id = ?", parentId).Scan(&list)
return &list
}
func connect() *gorm.DB{
db, err := gorm.Open(mysql.Open("root:123456@tcp(127.0.0.1:3306)/node?charset=utf8mb4&parseTime=True&loc=Local"), &gorm.Config{})
if err != nil{
log.Print("connect to mysql error")
}
return db
}
用Conn接受返回的db对象,表结构比较简单,用SelectNode足够解决查询问题。
构造树形结构
把构造过程分为两部分,首先获取所有的root(parentId == 0)并放入Array中,人后在根据每个root的id递归构造子树
TreeNode是树形结构的基本组成,除了具有Node的基本属性还有children
type TreeNode struct {
Node
children *[]TreeNode
}
func buildRoot(conn *Conn) *[]TreeNode{
var container []TreeNode
list := *conn.SelectNode("0")
for _, value := range list{
tr := &TreeNode{
Node: Node{
Id: value.Id,
ParentId: value.ParentId,
Value: value.Value,
},
}
container = append(container, *tr)
}
return &container
}
func build(container *[]TreeNode, conn *Conn) *[]TreeNode{
for i, value := range *container{
var children []TreeNode
list := conn.SelectNode(value.Id)
for _, node := range *list{
children = append(children, TreeNode{
Node: Node{Id: node.Id, ParentId: node.ParentId, Value:node.Value},
})
(*container)[i].children = &children
}
if value.children != nil{
build(value.children, conn)
}
}
return container
}