Go 中的多态关联如何查询

文档中只看到了多态关联的正向插入,但是对于反向的操作一直不知道怎么写

场景:有文章表和话题表,评论表中存放文章和话题的评论,一篇文章可以有多条评论,话题同样,一条评论只能关联一篇文章或者一个话题

希望结果:可以通过文章查询到该文章下所有评论,可以通过话题查询到所有评论,可以通过评论查询到话题或者文章

数据库存储数据:
Go 中的多态关联如何查询

models:

// 文章
type Article struct {
    ID   uint64 `gorm:"column:id;primaryKey;autoIncrement;" json:"id,omitempty"`
    Name string `json:"name"`

    Comment []Comment `gorm:"polymorphic:Owner;polymorphicValue:article;" json:"comment"`
}

func (Article) TableName() string {
    return "articles"
}

// 话题
type Topic struct {
    ID   uint64 `gorm:"column:id;primaryKey;autoIncrement;" json:"id,omitempty"`
    Name string `json:"name"`

    Comment []Comment `gorm:"polymorphic:Owner;polymorphicValue:topic;" json:"comment"`
}

func (Topic) TableName() string {
    return "topics"
}

// 评论 一条评论只能对应一条文章或一条话题
type Comment struct {
    ID      uint64 `gorm:"column:id;primaryKey;autoIncrement;" json:"id,omitempty"`
    Content string `json:"content"`

    OwnerType string `json:"owner_type"`
    OwnerID   uint64 `json:"owner_id"`

}

func (Comment) TableName() string {
    return "comments"
}

文章和话题可以正确获取评论

var article []models.Article
database.DB.Preload("Comment").Find(&article)

但是从评论获取文章和话题的查询语句不知道该如何写?期间查过百度也问过GPT,但是并没有实现(也挺疑惑的,这不应该是很常见的场景吗?为啥很少这样的写法,难道go中不这样实现吗)

Evn
讨论数量: 6

我是通过预加载解决问题,首先你需要声明一个对应结构存放到结构体中,让后在查询的时候使用预加载进行附带信息查询

// Article 直接对应到表结构
type Article struct {
    ID           uint64 `gorm:"primaryKey;autoIncrement;comment:帖子ID"`
    Title        string `gorm:"size:50;comment:帖子标题"`
    Content      string `gorm:"type:longtext;comment:帖子内容"`
    CommentCount uint64 `gorm:"comment:评论总数"`
    Status       uint8  `gorm:"comment:帖子状态 0:审核、1:正常、2:删除"`
    UserID       uint64 `gorm:"comment:作者ID"`
    CategoryID   uint64 `gorm:"comment:所属板块ID"`
    NiceTopic    uint8  `gorm:"comment:精选话题"`
    BrowseCount  uint64 `gorm:"comment:浏览量"`
    ThumbsUP     uint64 `gorm:"comment:点赞数"`

    Comments  []Comment         `gorm:"foreignKey:ArticleID;references:ID;"` // Article : Comment -> 1:N
    UserLikes []UserLikeArticle `gorm:"foreignKey:ArticleID;references:ID;"` // Article : Comment -> 1:N
    Tags      []Tag             `gorm:"many2many:article_tag"`               // Tag : Article -> N:N

    // 预加载模型
    User User

    Ctime int64 // 创建时间,毫秒作为单位
    Utime int64 // 更新时间,毫秒作为单位
}

// Comment 评论表
type Comment struct {
    ID        uint64 `gorm:"primaryKey;autoIncrement;comment:评论ID"`
    Content   string `gorm:"type:longtext;comment:评论内容"`
    UserID    uint64 `gorm:"comment:评论用户ID"`
    ArticleID uint64 `gorm:"comment:[外键]文章ID"`
    ParentID  uint64 `gorm:"index;not null;comment:父级评论ID"`
    Floor     uint32 `gorm:"index;not null;comment:评论楼层"`
    State     uint8  `gorm:"comment:该评论状态"`

    // 预加载模型 
    User User // 评论所属的用户信息,通过预加载获取(如果你要通过评论携带文章信息就再加个Article)

    Ctime int64 // 创建时间,毫秒作为单位
    Utime int64 // 更新时间,毫秒作为单位
}
// 这里我列举在评论表通过articleId查找所有评论并附带用户信息的操作。流程大致就是这样的
func (c *commentGORM) GetByArticleID(ctx context.Context, articleID uint64, paging *shared.Page) ([]model.Comment, error) {
    var comments []model.Comment
    err := c.db.WithContext(ctx).Preload("User").Scopes(paging.Paginate(&model.Comment{})).Where("article_id=?", articleID).Find(&comments).Error
    return comments, err
}
1年前 评论
mengxin666 (作者) 1年前
Evn_ (楼主) 1年前
mengxin666 (作者) 1年前
mengxin666 (作者) 1年前
Evn_ (楼主) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!