gorm / go 如何正确连接两个表?

Posted

技术标签:

【中文标题】gorm / go 如何正确连接两个表?【英文标题】:gorm / go how to join two tables properly? 【发布时间】:2022-01-12 17:54:54 【问题描述】:

我的消息结构;

type Message struct 
  Id          int    `json:"id" gorm:"primaryKey;AUTO_INCREMENT"`
  Message     string `json:"message"`
  Sender      int    `json:"sender" gorm:"foreignKey:users"`
  ChatId      int    `json:"chatid" gorm:"index"`
  CreatedAt   int64  `json:"createdat" gorm:"autoCreateTime"`
  MessageType int    `json:"messagetype"` // 0 representing text , 1 representing image
  Image       string `json:"image"`       // will be empty if the image doesn't contain image

我的用户结构;

type User struct 
  ID                 int    `gorm:"primaryKey;AUTO_INCREMENT"`
  Username           string `gorm:"not null"`
  Mail               string `gorm:"not null"`
  Password           string `gorm:"not null"`
  Updated            int64  `gorm:"autoUpdateTime:milli"`
  Created            int64  `gorm:"autoCreateTime"`
  RegisterMethod     string `gorm:"not null"`
  IsEmailValidated   bool   `gorm:"default:false"`
  IsOnboardCompleted bool   `gorm:"default:false"`

这是我的查询;

messages := []model.Message
err := r.db.Joins("inner join users on messages.sender = users.id").Where("chat_id = ?", chatid).Order("created_at desc").Limit(10).Find(&messages).Error

这是结果;

 
    "id": 1,
    "message": "csacsacsa",
    "sender": 16,
    "chatid": 0,
    "createdat": 0,
    "messagetype": 0,
    "image": ""
,

我想要实现的是,使用“发件人”部分加入用户对象,例如


        "id": 1,
        "message": "csacsacsa",
        "sender": 
          "id":16,
          "username": "bla bla bla",
          "mail": "bla bla bla" 
          ....
        ,
        "chatid": 0,
        "createdat": 0,
        "messagetype": 0,
        "image": ""
,

【问题讨论】:

【参考方案1】:

您需要在 Message 结构中添加一个字段,以便为发件人提供所有信息。

消息结构更改:

type Message struct 
  Id          int    `json:"id" gorm:"primaryKey;AUTO_INCREMENT"`
  Message     string `json:"message"`
  Sender      int    `json:"senderid" gorm:"foreignKey:users"`
  SenderObj   User   `json:"sender" gorm:"foreignKey:ID;references:Sender"`
  ChatId      int    `json:"chatid" gorm:"index"`
  CreatedAt   int64  `json:"createdat" gorm:"autoCreateTime"`
  MessageType int    `json:"messagetype"` 
  Image       string `json:"image"`       

有了这个,你可以使用Preload函数来加载SenderObj字段。

messages := []model.Message
err := r.db.Preload("SenderObj").Where("chat_id = ?", chatid).Order("created_at desc").Limit(10).Find(&messages).Error

【讨论】:

非常感谢您的回答,选择一些特殊的栏目怎么样?现在它返回整个用户对象和一些不必要的数据,比如密码电子邮件,我想从用户中挑选一些部分,比如用户名和 id 您可以查看gorm.io/docs/preload.html#Custom-Preloading-SQL。我知道这个特定问题有一个 SO 答案(使用 Preload 函数和 Select 函数),我现在似乎找不到它。

以上是关于gorm / go 如何正确连接两个表?的主要内容,如果未能解决你的问题,请参考以下文章

go项目中数据库连接,以及redis连接

GORM的简单使用

如何在 Gorm 中留下连接子查询计数

gorm基本使用

Go开源宝藏GORM 专场 (含思维导图) | 持续更新

Go组件学习——手写连接池并没有那么简单