为了账号安全,请及时绑定邮箱和手机立即绑定

如何(预加载)在自定义列上连接表?

如何(预加载)在自定义列上连接表?

Go
MYYA 2022-07-18 17:10:51
假设我们有以下模型: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 companyINNER 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 的方法?请记住,以上所有代码都是对真正问题的模拟,我不想公开原始模型/查询。
查看完整描述

2 回答

?
慕标琳琳

TA贡献1830条经验 获得超9个赞

您可以使用Preload加载Addresses到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)


查看完整回答
反对 回复 2022-07-18
?
四季花海

TA贡献1811条经验 获得超5个赞

如果您使用的是 Gorm v2,您可以通过关联对 has-one 和一对多执行 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 构建的查询 :)


查看完整回答
反对 回复 2022-07-18
  • 2 回答
  • 0 关注
  • 118 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信