go-gorm 查询多位字段
在PHP开发中,数据库操作是非常常见的任务。而在数据库操作中,查询多个字段是一种常见的需求。针对这一需求,go-gorm是一款强大的ORM库,可以帮助开发者快速、高效地查询多个字段。在本文中,php小编新一将为大家介绍如何在go-gorm中实现查询多个字段,并给出相应的示例代码,帮助大家轻松掌握这一技巧。无论是初学者还是有一定经验的开发者,本文都能为你提供有价值的帮助和指导。一起来看看吧!
问题内容
我有以下型号:
<code>type User struct { ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4();primary_key" json:"id"` ... } type Environment struct { ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4();primary_key" json:"id"` UserId uuid.UUID `gorm:"type:uuid" json:"userId"` User User `gorm:"foreignKey:UserId;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"` ... } type Secret struct { ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4();primary_key" json:"id"` UserId uuid.UUID `gorm:"type:uuid" json:"userId"` User User `gorm:"foreignKey:UserId;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"` Environments []Environment `gorm:"many2many:environment_secrets;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"environments"` ... } </code>
创建具有一个或多个环境的机密时,environment_secrets
表会根据有多少个环境共享相同的机密来创建一行或多行:
secret_id | environment_id -------------------------- uuid | uuid
我想做的是查询 secrets
表中的 environments
字段。
我遇到的问题是,虽然 Preload
将数据插入 environments
字段,但在 Find
子句期间它似乎不可用:
<code>var secrets []models.Secret if err := db.Preload("Environments").Find(&secrets, "user_id=? AND ? @> environments.id", userSessionId, environmentId).Error; err != nil { return c.Status(fiber.StatusOK).JSON( fiber.Map{"error": err.Error()}, ) } // ERROR: missing FROM-clause entry for table "environments" (SQLSTATE 42P01) </code>
简而言之,我正在尝试编写此查询:在“secrets”表中,查找拥有这些秘密的匹配 userId,并查看秘密中关联的“environments.id”字段以查找匹配的 UUID特定环境 UUID(它也将由该用户拥有)
。
例如,如果我使用此 92a4c405-f4f7-44d9-92df-76bd8a9ac3a6
用户 UUID 查询 secrets
以检查所有权,并使用此 cff8d599-3822-474d-a980-fb054fb9 进行查询23cc
环境UUID,那么结果输出应该看起来像...
<code>[ { "id": "63f3e041-f6d9-4334-95b4-d850465a588a", "userId": "92a4c405-f4f7-44d9-92df-76bd8a9ac3a6", // field to determine ownership by specific user "environments": [ { "id": "cff8d599-3822-474d-a980-fb054fb923cc", // field to determine a matching environment UUID "userId": "92a4c405-f4f7-44d9-92df-76bd8a9ac3a6", // owned by same user "name": "test1", "createdAt": "2023-08-24T09:27:14.065237-07:00", "updatedAt": "2023-08-24T09:27:14.065237-07:00" }, { "id": "65e30501-3bc9-4fbc-8b87-2f4aa57b461f", // this secret happens to also be shared with another environment, however this data should also be included in the results "userId": "92a4c405-f4f7-44d9-92df-76bd8a9ac3a6", // owned by same user "name": "test2", "createdAt": "2023-08-24T12:50:38.73195-07:00", "updatedAt": "2023-08-24T12:50:38.73195-07:00" } ], "key": "BAZINGA", "value": "JDJhJDEwJHR5VjRWZ3l2VjZIbXJoblhIMU1D", "createdAt": "2023-08-24T12:51:05.999483-07:00", "updatedAt": "2023-08-24T12:51:05.999483-07:00" } ...etc ] </code>
是否有一个 JOIN 查询或者可能是一个原始 SQL 查询,我可以编写以使 environments
行数据在 secrets
中可用以进行查询?
解决方法
不太漂亮,但是这个原始狗 GORM SQL 查询按预期工作:
SELECT * FROM ( SELECT s.id, s.user_id, s.key, s.value, s.created_at, s.updated_at, jsonb_agg(envs) as environments FROM secrets s JOIN environment_secrets es ON s.id = es.secret_id JOIN environments envs on es.environment_id = envs.id WHERE s.user_id = ? GROUP BY s.id ) r WHERE r.environments @> ?;
查询可以理解为...
将机密聚合为 r
(结果),其中 environments
字段具有:
- 与多对表秘密 ID 匹配的秘密 ID
- 与环境 ID 匹配的多表环境 ID
- 并根据与参数用户 ID 匹配的秘密用户 ID 进行过滤
从 r
(结果)中查找 environments
JSON 数组中的部分参数化 id
。
以及一些使用 go Fiber 的示例 Go 代码:
import ( "time" "github.com/gofiber/fiber/v2" "github.com/google/uuid" "gorm.io/datatypes" ) type SecretResult struct { ID uuid.UUID `json:"id"` UserId uuid.UUID `json:"userId"` Environments datatypes.JSON `json:"environments"` Key string `json:"key"` Value []byte `json:"value"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } func Example(c *fiber.Ctx) error { db := database.ConnectToDB(); userSessionId := c.Locals("userSessionId").(uuid.UUID) parsedEnvId, err := uuid.Parse(c.Params("id")) if err != nil { return c.Status(fiber.StatusBadRequest).JSON( fiber.Map{"error": "You must provide a valid environment id!"}, ) } var secrets []SecretResult if err := db.Raw(` USE SQL QUERY MENTIONED ABOVE `, userSessionId,`[{"id":"`+parsedEnvId.String()+`"}]`), ).Scan(&secrets).Error; err != nil { fmt.Printf("Failed to load secrets with %s: %s", parsedEnvId, err.Error()) return c.Status(fiber.StatusInternalServerError).JSON( fiber.Map{"error": "Failed to locate any secrets with that id."}, ) } return c.Status(fiber.StatusOK).JSON(secrets) }
以上是go-gorm 查询多位字段的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Golang在性能和可扩展性方面优于Python。1)Golang的编译型特性和高效并发模型使其在高并发场景下表现出色。2)Python作为解释型语言,执行速度较慢,但通过工具如Cython可优化性能。

Golang在并发性上优于C ,而C 在原始速度上优于Golang。1)Golang通过goroutine和channel实现高效并发,适合处理大量并发任务。2)C 通过编译器优化和标准库,提供接近硬件的高性能,适合需要极致优化的应用。

GoimpactsdevelopmentPositationalityThroughSpeed,效率和模拟性。1)速度:gocompilesquicklyandrunseff,ifealforlargeprojects.2)效率:效率:ITScomprehenSevestAndArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增强开发的简单性:3)SimpleflovelmentIcties:3)简单性。

Golang和Python各有优势:Golang适合高性能和并发编程,Python适用于数据科学和Web开发。 Golang以其并发模型和高效性能着称,Python则以简洁语法和丰富库生态系统着称。

Golang适合快速开发和并发场景,C 适用于需要极致性能和低级控制的场景。1)Golang通过垃圾回收和并发机制提升性能,适合高并发Web服务开发。2)C 通过手动内存管理和编译器优化达到极致性能,适用于嵌入式系统开发。

Golang和C 在性能上的差异主要体现在内存管理、编译优化和运行时效率等方面。1)Golang的垃圾回收机制方便但可能影响性能,2)C 的手动内存管理和编译器优化在递归计算中表现更为高效。

C 更适合需要直接控制硬件资源和高性能优化的场景,而Golang更适合需要快速开发和高并发处理的场景。1.C 的优势在于其接近硬件的特性和高度的优化能力,适合游戏开发等高性能需求。2.Golang的优势在于其简洁的语法和天然的并发支持,适合高并发服务开发。

Golang和C 在性能竞赛中的表现各有优势:1)Golang适合高并发和快速开发,2)C 提供更高性能和细粒度控制。选择应基于项目需求和团队技术栈。
