【问题标题】:Get GORM model row based on foreign key relationship (golang)根据外键关系获取GORM模型行(golang)
【发布时间】:2021-10-02 17:27:21
【问题描述】:

我正在使用 Golang (GORM) + Postgres。我正在尝试模拟一种业务情况,即卖家向买家出售商品,每个买家都创建一个订单交易。

我有一个 Order Gorm 模型,以及一个买方和卖方 Gorm 模型。买方和卖方已经是在数据库中创建的行。

一个买家有很多订单。

一个卖家有很多订单。

为了绘制这种关系,我相信我只是创建了相应的买方/卖方结构(标准 Gorm 模型),然后像这样创建一个 Order 结构:

type Order struct {
    ID        int64       `json:"ID"gorm:"primary_key;auto_increment:true"`
    Buyer     *Buyer      `json:"Buyer"`
    Seller    *Seller     `json:"Seller"`
    // ... other data ...
}

我假设上面会自动创建关系,但我不完全确定。我可以用这个函数创建一个订单,并且返回正常:

func CreateOrder(buyer *entity.Buyer, seller *entity.Seller) (*entity.Order, error) {
    order := &entity.Order{
        User:   buyer,
        Sitter: seller,
        // ... other data ...
    }
    db.Table("orders").Create(order)
    return order
}

如果我使用 Postgres CLI,TABLE orders; 不会显示买家或卖家列。我希望有一列他们的 ID。所以这就是为什么我不确定这是否有效。 这本身肯定是个问题。

无论如何,我真正想要做的是能够检查当前是否存在买方/卖方的任何订单。但我真的不认为用 gorm 查询来做到这一点。我想在 SQL 中它会是这样的:

func FindOrder(buyer *entity.Buyer, seller *entity.Seller) {
     db.Raw(`GET order FROM orders WHERE buyer = ?, seller = ?`, buyer, seller)
     // OR this ???
     db.Table("orders").First(buyer, buyer).First(seller, seller)
}

但我不知道有任何 Gorm 辅助函数可以真正做到这一点。我也希望这能有效,因为买家和卖家都有自己的 ID 主键。

我怎样才能像上面的例子那样根据买家/卖家找到订单?

作为替代方案,我正在考虑添加(买家 ID + 卖家 ID)来制作自定义订单 ID primary_key。不过,这似乎很老套,因为我觉得关系的全部意义在于,我不必做这样的事情。

【问题讨论】:

    标签: database postgresql go orm go-gorm


    【解决方案1】:

    如果您需要在订单表中查看卖家 ID 和买家 ID,请在您的订单结构中包含两个字段,您也可以使用 foreignKey 标签填充这些字段(默认情况下填充关联表记录的主ID,您可以使用references 标记,如here 所述来更改)。

    type Order struct {
        ID int64 `json:"id" gorm:"primaryKey;autoIncrement:true"`
        BuyerID int64 `json:"buyer_id" gorm:"index"`
        SellerID int64 `json:"seller_id" gorm:"index"`
        Buyer *Buyer `json:"buyer" gorm:"foreignKey:BuyerID"`
        Seller *Seller  `json:"seller" gorm:"foreignKey:SellerID"`
    }
    
    type Buyer struct {
        ID int64    `json:"id" gorm:"primaryKey;autoIncrement:true"`
        Name string `json:"name"`
    }
    
    type Seller struct {
        ID int64    `json:"id" gorm:"primaryKey;autoIncrement:true"`
        Name string  `json:"name"`
    }
    

    至于在给定买家和卖家的情况下查找订单的功能,您可以使用类似的功能,

    func findOrders(db *gorm.DB, buyerID int,sellerID int)[]Order{
        orders := make([]Order,0)
        db.Where("buyer_id=? AND seller_id=?",buyerID,sellerID).Find(&Order{}).Scan(&orders)
        return orders
    }
    

    相比之下,如果您需要查找给定买家或卖家的订单,

    func findOrder(db *gorm.DB, buyerID int,sellerID int)[]Order{
        orders := make([]Order,0)
        db.Where("buyer_id=? OR seller_id=?",buyerID,sellerID).Find(&Order{}).Distinct().Scan(&orders)
        return orders
    }
    

    index 标签涵盖了orders 表的索引要求。

    【讨论】:

    • 谢谢这是完美的!其他快速问题,为什么它的格式是 gorm:"primary_key" vs camel-case gorm:"foreignKey"
    • @RonGermano 道歉。那必须是骆驼案。以上编辑。
    • 你确定不是反过来吗?我一直在查看一堆代码 sn-ps 和 IIRC“primary_key”格式实际上是 正确的 方式来做到这一点。我想有一个混合的共识和过时的文档没有帮助。
    • @RonGermano 我正在使用最新版本的 v1.21.12 和最新的文档,驼峰式大小写是文档中提供的约定。但是,对于主键,从代码github.com/go-gorm/gorm/blob/… 中可以看出,您似乎可以同时使用蛇和骆驼大小写
    【解决方案2】:

    对大型查询使用简单的原始查询构建器 https://perfilovstanislav.github.io/go-raw-postgresql-builder/#simple-example

    【讨论】:

      猜你喜欢
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多