如何嵌套查询child的child table数据
How to nest query child's child table data
我有一个多对多 table 调用用户 -> 任务,我可以用这个查询任务:
var user models.User
DB.Find(&user, "user_addr=?", userAddr)
//log.Infof("find user: ", user)
DB.Model(&user).Related(&tasks, "Tasks")
但是,在我的任务中,我有一个子任务 table 是一对多的,称为子任务。我如何将其作为任务中的字段查询出来。这是我的任务结构:
type Tasks struct {
gorm.Model
TasksID int `json:"tasks_id"`
// TasksCreateTime is the hash value since it is unique
//TasksHash string `json:"tasks_hash"`
// tasks related fields
TasksTitle string `json:"tasks_title"`
TasksCreateTime time.Time `json:"tasks_create_time"`
TasksComment string `json:"tasks_comment"`
SubTasks []SubTask `json:"sub_tasks" gorm:"foreignkey:ID"`
}
我想查询出数据并将其分配给 SubTasks 字段。
如何嵌套?
这种方式行得通吗?
func FetchSyncTasksForUser(userAddr string, tasks *[]models.Tasks) {
log.Infof("fetch sync tasks for user %s ", userAddr)
var user models.User
DB.Find(&user, "user_addr=?", userAddr)
DB.Preload("Tasks").Preload("Tasks.SubTasks").Find(&user, "user_addr = ?", userAddr)
tasks = &user.Tasks
}
您是否尝试过 gorm 预加载功能?我将预加载必要模型的代码片段放在一起。它会将格式化后的模型打印到命令行。
更新:包括一个片段以通过 ID 查找用户 https://gorm.io/docs/query.html
package main
import (
"encoding/json"
"fmt"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type User struct {
gorm.Model
Name string
Tasks []Task
}
type Task struct {
gorm.Model
UserId uint
SubTasks []SubTask
}
type SubTask struct {
gorm.Model
TaskId uint
}
func main() {
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// Migrate the schema
db.AutoMigrate(&User{}, &Task{}, &SubTask{})
// Create
user := User{Name: "C"}
db.Create(&user)
task := Task{UserId: user.ID}
db.Create(&task)
subTaskOne := SubTask{TaskId: task.ID}
subTaskTwo := SubTask{TaskId: task.ID}
db.Create(&subTaskOne)
db.Create(&subTaskTwo)
// Find all users, with tasks and subtasks
users := make([]User, 1)
db.Preload("Tasks").Preload("Tasks.SubTasks").Find(&users)
for _, u := range users {
jsonOutput, err := json.MarshalIndent(u, "", " ")
if err != nil {
panic("")
}
fmt.Println(string(jsonOutput))
}
// Find only one user by user_addr with tasks and subtasks
oneUser := User{}
db.Where("user_addr = ?", user.UserAddr).Preload("Tasks").Preload("Tasks.SubTasks").First(&oneUser)
jsonOutput, err := json.MarshalIndent(oneUser, "", " ")
if err != nil {
panic("")
}
fmt.Println(string(jsonOutput))
// Clean up
db.Delete(&subTaskTwo)
db.Delete(&subTaskOne)
db.Delete(&task)
db.Delete(&user)
}
我有一个多对多 table 调用用户 -> 任务,我可以用这个查询任务:
var user models.User
DB.Find(&user, "user_addr=?", userAddr)
//log.Infof("find user: ", user)
DB.Model(&user).Related(&tasks, "Tasks")
但是,在我的任务中,我有一个子任务 table 是一对多的,称为子任务。我如何将其作为任务中的字段查询出来。这是我的任务结构:
type Tasks struct {
gorm.Model
TasksID int `json:"tasks_id"`
// TasksCreateTime is the hash value since it is unique
//TasksHash string `json:"tasks_hash"`
// tasks related fields
TasksTitle string `json:"tasks_title"`
TasksCreateTime time.Time `json:"tasks_create_time"`
TasksComment string `json:"tasks_comment"`
SubTasks []SubTask `json:"sub_tasks" gorm:"foreignkey:ID"`
}
我想查询出数据并将其分配给 SubTasks 字段。
如何嵌套?
这种方式行得通吗?
func FetchSyncTasksForUser(userAddr string, tasks *[]models.Tasks) {
log.Infof("fetch sync tasks for user %s ", userAddr)
var user models.User
DB.Find(&user, "user_addr=?", userAddr)
DB.Preload("Tasks").Preload("Tasks.SubTasks").Find(&user, "user_addr = ?", userAddr)
tasks = &user.Tasks
}
您是否尝试过 gorm 预加载功能?我将预加载必要模型的代码片段放在一起。它会将格式化后的模型打印到命令行。
更新:包括一个片段以通过 ID 查找用户 https://gorm.io/docs/query.html
package main
import (
"encoding/json"
"fmt"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type User struct {
gorm.Model
Name string
Tasks []Task
}
type Task struct {
gorm.Model
UserId uint
SubTasks []SubTask
}
type SubTask struct {
gorm.Model
TaskId uint
}
func main() {
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// Migrate the schema
db.AutoMigrate(&User{}, &Task{}, &SubTask{})
// Create
user := User{Name: "C"}
db.Create(&user)
task := Task{UserId: user.ID}
db.Create(&task)
subTaskOne := SubTask{TaskId: task.ID}
subTaskTwo := SubTask{TaskId: task.ID}
db.Create(&subTaskOne)
db.Create(&subTaskTwo)
// Find all users, with tasks and subtasks
users := make([]User, 1)
db.Preload("Tasks").Preload("Tasks.SubTasks").Find(&users)
for _, u := range users {
jsonOutput, err := json.MarshalIndent(u, "", " ")
if err != nil {
panic("")
}
fmt.Println(string(jsonOutput))
}
// Find only one user by user_addr with tasks and subtasks
oneUser := User{}
db.Where("user_addr = ?", user.UserAddr).Preload("Tasks").Preload("Tasks.SubTasks").First(&oneUser)
jsonOutput, err := json.MarshalIndent(oneUser, "", " ")
if err != nil {
panic("")
}
fmt.Println(string(jsonOutput))
// Clean up
db.Delete(&subTaskTwo)
db.Delete(&subTaskOne)
db.Delete(&task)
db.Delete(&user)
}