【问题标题】:GORM how to Joins Preloading and user filter as wellGORM 如何加入预加载和用户过滤器
【发布时间】:2022-01-09 11:29:08
【问题描述】:

我是 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
}

在原始 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)

我发现它离开了两次加入父亲和盛大
先加入Father as Father获取父亲专栏
发送是我的自定义左加入
我怎样才能只加入一次(“父亲”)并使用它的列进行过滤

【问题讨论】:

    标签: go go-gorm


    【解决方案1】:

    假设你想坚持使用这些结构名称,有几件事需要做。

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

    func (SonModel) Table() string {
       return "son"
    }
    func (FaterModel) Table() string {
       return "father"
    }
    func (GrandModel) Table() string {
       return "grand"
    } 
    

    完成后,您可以这样编写查询:

    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
    

    【讨论】:

      【解决方案2】:

      我试试这个代码

      sql := db.ToSQL(func(tx *gorm.DB) *gorm.DB {
              return tx.Model(&SonModel{}).Select("son.id, son.name, father.*").Joins("left join father on father.id = son.id").Where("son.name LIKE ?", "%name%").Where("father.name LIKE ?", "%name%").Where("age = ?", 15).Scan(&SonModel{})
          })
      fmt.Println(sql)
      

      结果

      SELECT son.id, son.name, father.* FROM "son_models" left join father on father.id = son.id WHERE son.name LIKE '%name%' AND father.name LIKE '%name%' AND age = 15

      这能解决你的问题吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多