【问题标题】:How (preloading) join table on custom column?如何(预加载)在自定义列上连接表?
【发布时间】:2020-12-10 10:26:22
【问题描述】:

假设我们有以下模型:

type Company struct {
    gorm.Model
    Name string
    Addresses []Address
}

type Address struct {
    gorm.Model
    CompanyID uint64
    Street string
    City string
    Country string
}

我想获取在特定位置有地址的所有公司(及其地址)。像这样的:

SELECT company.*, address.* FROM company
INNER JOIN address ON address.company_id = company.id AND address.country = 'Bulgaria'

因此,如果一家公司在特定位置没有地址,我根本不会得到它。我正在尝试这样的事情:

db.Joins("Addresses", "addresses.country = ?", "Bulgaria").Find(&companies)

但是,它不起作用,因为 GORM 不接受 Joins 的第二个参数(在使用预加载连接时),所以我应该检查生成的查询并进行类似的操作:

db.Where(`"Address".country = ?`, "Bulgaria").Joins("Addresses").Find(&companies)

有没有更好的方法/不是 hacky 的方法?请记住,以上所有代码都是对真正问题的模拟,我不想暴露原始模型/查询。

【问题讨论】:

  • 你为什么使用LEFT JOIN?它会给你所有的公司。
  • @Popeye 我的错,已编辑

标签: sql postgresql go go-gorm


【解决方案1】:

您可以使用PreloadAddresses 加载到Company 对象中。

根据您描述的条件,如果您不想加载与您的过滤器不匹配的公司,您应该使用INNER JOIN

两种选择:

首先,如果您的表名为company,那么您的查询应该如下所示:

db.Table("company").
   Preload("Addresses").
   Joins("INNER JOIN addresses a ON a.company_id = company.id").
   Where("a.country = ?", "Bulgaria").
   Find(&companies)

其次,如果你的表名为companies,那么你应该试试这个:

db.Preload("Addresses").
   Joins("INNER JOIN addresses a ON a.company_id = companies.id").
   Where("a.country = ?", "Bulgaria").
   Find(&companies)

【讨论】:

  • 请注意,该表可以命名为company,如果您为gorm.Open 提供了SingularTable: true NamingStrategy 选项,则可以使用第二个示例。
【解决方案2】:

如果你使用 Gorm v2,你可以通过 associations 对 has-one 和 one-to-many 执行 CRUD 操作:

var companies []Company
var addresses []Address
countries := []string{"Bulgaria"}
db.Model(&Address).Where("country IN (?)", countries).Find(&addresses)

// The key is using the previously fetched variable as the model for the association query 
db.Model(&addresses).Association("CompanyID").Find(&companies)

这也适用于多对多关系。

在比较 Gorm 与原始 SQL 查询 (db.Raw(SQLquery)) 时,您通常会看到性能下降。从好的方面来说,您不必处理在 Go 中构建原始 sql 字符串所增加的复杂性,这非常好。我个人在我的项目中使用原始查询和 gorm 构建查询的组合 :)

【讨论】:

    猜你喜欢
    • 2010-09-12
    • 2022-01-23
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 1970-01-01
    • 2015-04-02
    相关资源
    最近更新 更多