卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章35012本站已运行393

如何查询关系的嵌入值等于特定值的模型?

如何查询关系的嵌入值等于特定值的模型?

在开发和设计数据库模型时,有时我们需要查询关系中的嵌入值是否等于特定值。这个问题在实际应用中经常遇到,但解决起来可能并不容易。在本文中,我将向大家介绍一种有效的方法来查询关系的嵌入值是否等于特定值的模型。无需担心,我会用简明易懂的语言解释清楚,帮助您快速理解并应用到实际开发中。让我们一起来看看吧!

问题内容

我有两个不同的模型(carstypes),它们彼此相关(属于关系),其中两个模型都有一个嵌入式 struct 用于公共数据(post)。我想检索某些 types,但只想收到 postcars 值等于某个值的答案。

shorty说,根据下面的模型,我想找到所有types,其中cars.post.published等于true。

模型

type post struct {
  published bool
}

type car struct {
  gorm.model
  brand string
  post post `gorm:"embedded"`
}

type type struct {
  gorm.model
  name string
  carid uint32
  car car
  post post `gorm:"embedded"`
}

使用 db.preload("car").find(&type) 我能够在答案对象中获取 car 值。如果我在 car 结构上使用 where() 函数(即 where(car{brand: "volvo"}) 我可以通过 brand 获取值,但是当使用 post 时(即 where(car{post: post {published: true})) 它只会返回所有内容。

我最好使用需要查询的主模型作为 where() 函数的基础。例如:

q := Type{Car: Car{Post: Post{Published: true}}}
db.Preload("Car").Where(q).Find(&Type)

...但这似乎不起作用。如何在不使用原始 sql 生成器的情况下实现这样的查询?

解决方法

我能够通过以下方式解决您的问题。首先,我将分享代码,然后我将介绍值得解释的要点。

package main

import (
    "fmt"

    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

type Post struct {
    Published bool
}

type Car struct {
    gorm.Model
    Brand  string
    TypeID int
    Type   Type
    Post   Post `gorm:"embedded"`
}

type Type struct {
    gorm.Model
    Name  string
    CarID int
    Post  Post `gorm:"embedded"`
}

func main() {
    dsn := "host=localhost port=54322 user=postgres password=postgres dbname=postgres sslmode=disable"
    db, err := gorm.Open(postgres.Open(dsn))
    if err != nil {
        panic(err)
    }
    db.AutoMigrate(&Car{})
    db.AutoMigrate(&Type{})

    // uncomment these to seed data
    // db.Create(&Car{Brand: "Tesla", Type: Type{Name: "SUV", Post: Post{Published: true}}, Post: Post{Published: true}})
    // db.Create(&Car{Brand: "Ford", Type: Type{Name: "City", Post: Post{Published: false}}, Post: Post{Published: false}})

    var cars []Car
    if err := db.Debug().Model(&Car{}).Preload("Type").Where(&Car{Post: Post{Published: true}}).Find(&cars).Error; err != nil {
        panic(err)
    }
    for _, v := range cars {
        fmt.Println(v.Type.Name)
    }
}

现在,让我分享一些见解。

结构体定义

我稍微改变了它来处理这个场景。我从 type 结构中删除了 car 字段,并在 car 结构定义中添加了其对应项。

设置和种子

然后,我通过 gorm 设置了数据库连接。我将代码中定义的模型与数据库中存在的关系同步。为了演示,我手动播种了一些虚拟数据。

读取逻辑

然后,我运行查询来获取相关数据。我使用了以下方法:

  1. debug:用于记录实际的sql语句
  2. model:用于指定我们要处理的关系
  3. preload:用于加载type关联
  4. where:用于指定条件(在我们的例子中,过滤器位于嵌入结构上)
  5. find:用于将结果映射到变量

请告诉我这是否有助于解决您的问题,谢谢!

卓越飞翔博客
上一篇: 如何在Go中检测图像中的二维码?
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏