【问题标题】:Fetching a struct and other data in one query在一个查询中获取结构和其他数据
【发布时间】:2021-01-18 14:27:16
【问题描述】:

我有以下表架构:

user
-----
id uuid
name string

user_model
------
id uuid
user_id uuid
model_id uuid
role int

model
_____
id uuid
name string
model_no string

我有以下代码从“模型”表中获取数据。

underlyingModel = &model{}
var model IModel
model = underlyingModel
role := 0

db.Table("model").Joins('INNER JOIN user_model ON user.id = user_model.uuid')
.Joins('INNER JOIN model ON user.id = model_id').Find(&model);

在我的实际代码中,模型可以是许多不同的结构类型,具有不同的字段,它们都在IModel接口后面。

我想做的是在一个查询中从user_model 中获取额外的role 字段。类似.Find(&model, &role)

是否可以使用 Gorm?

【问题讨论】:

    标签: database postgresql go orm go-gorm


    【解决方案1】:

    一种可能的解决方案是创建一个匿名结构来将结果放入其中,并结合Select() 方法。

    var selectModel struct {
       ID string //I'm assuming uuid matches the string
       Name string
       ModelNo string
       Role int
    }
    
    db.Table("model").
       Joins("INNER JOIN user_model ON user.id = user_model.uuid").
       Joins("INNER JOIN model ON user.id = model_id").
       Select("model.id, model.name, model.model_no, user_model.role").
       Find(&selectModel);
    

    基本上,您使用selectModel 变量创建一个匿名结构,其中包含您要返回的所有字段。然后,您需要执行一个 select 语句,因为您需要一些不属于 model 表的字段。

    Here您可以在表单中找到有关智能选择字段的更多信息。

    编辑:

    根据来自 cmets 的其他信息,有一个可行的解决方案。

    您的IModel 接口在其签名中可能有两种方法,一种用于为 SQL 查询的SELECT 部分提取字符串,另一种用于获取您将使用的selectModel 的指针Find 方法。

    type IModel interface {
      SelectFields() string
      GetSelectModel() interface{}
    }
    

    实现是这样的:

    func (m *model) SelectFields() string {
      return "model.id, model.name, model.model_no, user_model.role"
    }
    
    func (m *model) GetSelectModel() interface{} {
      return &m.selectModel
    }
    
    type model struct {
     selectModel
     ID uint64
     Age int
    }
    
    
    type selectModel struct {
      Name string
      Email string
    }
    

    然后,您的查询可能如下所示:

       var m IModel
       m = model{}
    
       db.Table("model").
       Joins("INNER JOIN user_model ON user.id = user_model.uuid").
       Joins("INNER JOIN model ON user.id = model_id").
       Select(m.GetSelectFields()).
       Find(m.GetSelectModel());
    

    【讨论】:

    • 我不能像你那样把它命名为id、name、modelno,因为我不会提前知道字段的名称,可能会有所不同。我想知道是否可以使用结构嵌入,在selectModel 中嵌入IModel 接口。
    • IModel 能否有一个SelectFields 方法(或类似的方法),它会提供需要添加到 SQL SELECT 语句中的字段列表?
    • 我猜 Gorm 可能有类似的东西来实现它的 ORM 魔法,但我不明白它的代码。我专门为此目的依靠它的魔力,所以我的 CRUD 操作可以忽略模型的类型。我尝试嵌入一个使用反射创建的 IModel 并将其嵌入到具有 Role 的结构中,但它不起作用。我想我暂时会做两个查询。感谢您的帮助。
    • 第一个例子奏效了。该结构应该只有您期望从查询中获得的db:"id" 表列,您会没事的。编辑的部分只是一个矫枉过正。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    相关资源
    最近更新 更多