如何在 GORM 中连接两个表

How to join two tables in GORM

我有两个表,

SET search_path = public;


CREATE TABLE IF NOT EXISTS changelog
(
    id          BIGINT NOT NULL PRIMARY KEY,
    object_type TEXT,
    object_id   BIGINT,
    parent_type TEXT,
    parent_id   BIGINT,
    action      TEXT,
    field       TEXT,
    old_value   TEXT,
    new_value   TEXT,
    comment_id  INTEGER,
    created_on  TIMESTAMP WITHOUT TIME ZONE,
    created_by  BIGINT
);

CREATE TABLE IF NOT EXISTS changelog_comments
(
    id         INTEGER NOT NULL PRIMARY KEY,
    comment    TEXT,
    created_on TIMESTAMP WITHOUT TIME ZONE,
    created_by BIGINT
);

SET search_path = DEFAULT;

我想为 returns 字段

的变更日志实施搜索方法
"objectType"
"objectId"
"parentType"
"parentId"
"action"
"field"
"oldValue"
"newValue"
"comment"
"createdBy"
"createdOn"

如您所见,结果来自两个表的连接。

我找到了 https://gorm.io/docs/preload.html,但老实说,我不明白我怎样才能实现我所需要的。

我认为类似以下内容可能会有所帮助

type ChangelogResponseItem struct {
    ObjectType string     `json:"objectType"`
    ObjectID   uuid.UUID  `json:"objectId"`
    ParentType string     `json:"parentType"`
    ParentID   uuid.UUID  `json:"parentId"`
    Action     string     `json:"action"`
    Field      *string    `json:"field"`
    OldValue   *string    `json:"oldValue"`
    NewValue   *string    `json:"newValue"`
    Comment    *string    `json:"comment"`
    CreatedBy  *uint64    `json:"createdBy"`
    CreatedOn  *time.Time `json:"createdOn"`
}

问题是如何从 GORM 中提到的表格中得到我提到的内容?

一种方法是结合 JoinsSelect 方法来获得您想要的。根据您的 table,它看起来像这样:

list := []ChangelogResponseItem{}
tx := db.Table("changelog").
         Joins("INNER JOIN changelog_comments cc ON cc.id = changelog.comment_id").
         Select("changelog.objectType, changelog.object_type, changelog.object_id, changelog.parent_type, changelog.parent_id, changelog.action, changelog.field, changelog.old_value, changelog.new_value, cc.comment, changelog.created_on, changelog.created_by").
         Find(&list)
if tx.Error != nil {
  // handle error
}

这只是 return 数据,搜索将包括其他 Where 方法。

编辑:

带有预加载选项的解决方案:

结构:

type ChangelogComment struct {
  ID uint64 `json:"id"`
  Comment string `json:"comment"`
}

type Changelog struct {
    ObjectType string     `json:"objectType"`
    ObjectID   uuid.UUID  `json:"objectId"`
    ParentType string     `json:"parentType"`
    ParentID   uuid.UUID  `json:"parentId"`
    Action     string     `json:"action"`
    Field      *string    `json:"field"`
    OldValue   *string    `json:"oldValue"`
    NewValue   *string    `json:"newValue"`
    CommentID    uint64    `json:"comment_id"`
    Comment    *ChangelogComment `json:"comment"` 
    CreatedBy  *uint64    `json:"createdBy"`
    CreatedOn  *time.Time `json:"createdOn"`
}

使用 Preload 方法编码:

list := []Changelog{}
tx := db.Preload("Comment").Find(&list)
if tx.Error != nil {
  // handle error
}

请注意,在这种情况下,您将有一个不同的 JSON 对象,该对象的结构不会是扁平的,因为您也将有一个 comment 字段。