GORM 如何加入预加载和用户过滤

Tod*_*odd 1 go go-gorm

我是 golang 和 Gorm 的新手,
这是我的结构

type SonModel struct {
 ID int64
 Age int
 Name string
 FatherID int64
 Father FaterModel `gorm:"foreignKey:ID;references:FatherID"`
}

type FaterModel struct {
 ID int64
 Name string
 GrandID int64
 Grand GrandModel  `gorm:"foreignKey:ID;references:GrandID"`
}

type GrandModel struct {
 ID int64
 Name string
}
Run Code Online (Sandbox Code Playgroud)

在原始sql中我想要的是
select son.id,son.name,to_json(father.*) father from son join father on father.id = son.father_id where (son.name like '%name%' or father.name like '%name%') and son.age = 15
我想与父亲一起加入和过滤

在戈尔姆我正在做的是

db = db.Joins("Father").Preload("Father.Grand")
db = db.Joins("left join father on father.id = son.id left join grand on grand.id = father.grand_id")
db = db.Where("age = ?",15)
db = db.Where("father.name like ? or son.name like ? or grand.name like ?",name)
Run Code Online (Sandbox Code Playgroud)

我发现它左连接父亲和盛大两次
首先将父亲作为父亲连接以获取父亲的列
发送是我的自定义左连接
我如何仅加入(“父亲”)一次并使用其列进行过滤

Emi*_*vic 5

假设您想坚持使用这些结构名称,则需要完成几件事。

首先,按照惯例,GORM 根据结构名称确定表名称。如果您想使用不同的名称,则需要Tabler为每个模型实现该接口。像这样的东西:

func (SonModel) Table() string {
   return "son"
}
func (FaterModel) Table() string {
   return "father"
}
func (GrandModel) Table() string {
   return "grand"
} 
Run Code Online (Sandbox Code Playgroud)

完成此操作后,您可以像这样编写查询:

var sons []SonModel

name = fmt.Sprintf("%%%s%%", name) //for example, output in the resulting query should be %John%
err := db.Preload("Father.Grand").
          Joins("left join father on father.id = son.father_id").
          Joins("left join grand on grand.id = father.grand_id").
          Where("sone.age = ?", 15).
          Where("son.name like ? or father.name like ? or grand.name like ?", name, name, name).
          Find(&sons).Error
Run Code Online (Sandbox Code Playgroud)