我正在尝试通过构建一个小型原型订单管理应用来学习Go和Gorm . 数据库是MySQL . 通过简单的查询,Gorm一直很出色 . 然而,当试图获得涉及一对多与一对一关系的组合的结果集时,Gorm似乎不足 . 毫无疑问,我缺乏理解实际上是在做空 . 我似乎无法找到任何我想要完成的在线示例 . 任何帮助将不胜感激 .
Go Structs
// Order
type Order struct {
gorm.Model
Status string
OrderItems []OrderItem
}
// Order line item
type OrderItem struct {
gorm.Model
OrderID uint
ItemID uint
Item Item
Quantity int
}
// Product
type Item struct {
gorm.Model
ItemName string
Amount float32
}
Database tables
orders
id | status
1 | pending
order_items
id | order_id | item_id | quantity
1 | 1 | 1 | 1
2 | 1 | 2 | 4
items
id | item_name | amount
1 | Go Mug | 12.49
2 | Go Keychain | 6.95
3 | Go T-Shirt | 17.99
Current query
order := &Order
if err := db.Where("id = ? and status = ?", reqOrder.id, "pending")
.First(&order).Error; err != nil {
fmt.Printf(err.Error())
}
db.Model(&order).Association("OrderItems").Find(&order.OrderItems)
Results (gorm makes 2 db queries)
order == Order {
id: 1,
status: pending,
OrderItems[]: {
{
ID: 1,
OrderID: 1,
ItemID: 1,
Item: nil,
Quantity: 1,
},
{
ID: 2,
OrderID: 1,
ItemID: 2,
Item: nil,
Quantity: 4,
}
}
Alternative query
order := &Order
db.Where("id = ? and status = ?", reqOrder.id, "cart")
.Preload("OrderItems").Preload("OrderItems.Item").First(&order)
Results (gorm makes 3 db queries)
order == Order {
id: 1,
status: pending,
OrderItems[]: {
{
ID: 1,
OrderID: 1,
ItemID: 1,
Item: {
ID: 1,
ItemName: Go Mug,
Amount: 12.49,
}
Quantity: 1,
},
{
ID: 2,
OrderID: 1,
ItemID: 2,
Item: {
ID: 2,
ItemName: Go Keychain,
Amount: 6.95,
},
Quantity: 4,
}
}
Ideal results
上面的“替代查询”产生理想的查询结果 . 但是,Gorm会进行3次单独的数据库查询 . 理想情况下,使用1(或2)个数据库查询可以完成相同的结果 .
这可以通过几个连接在MySQL中完成 . Gorm允许连接 . 但是,我希望利用一些Gorm的关系魔法 .
谢谢你!
1 回答
如issue中所述,gorm不是为了使用连接来预加载其他结构值而设计的 . 如果您想继续使用gorm并且能够使用连接来加载值,则必须使用gorm中公开的SQL Builder,并编写一些代码来扫描所需的值 .
如果有许多表需要考虑,这将变得繁重 . 如果xorm可用作选项,则它们支持加载struct值 . 在查找项目符号下描述,here .
注意:我没有扫描所有字段,只是足以得到重点 .
EXAMPLE :
Output :