go-gorm 查询多位字段

go-gorm 查询多位字段

在PHP开发中,数据库操作是非常常见的任务。而在数据库操作中,查询多个字段是一种常见的需求。针对这一需求,go-gorm是一款强大的ORM库,可以帮助开发者快速、高效地查询多个字段。在本文中,php小编新一将为大家介绍如何在go-gorm中实现查询多个字段,并给出相应的示例代码,帮助大家轻松掌握这一技巧。无论是初学者还是有一定经验的开发者,本文都能为你提供有价值的帮助和指导。一起来看看吧!

问题内容

我有以下型号:

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"`    ...}

登录后复制

创建具有一个或多个环境的机密时,environment_secrets 表会根据有多少个环境共享相同的机密来创建一行或多行:

secret_id | environment_id--------------------------uuid      | uuid

登录后复制

我想做的是查询 secrets 表中的 environments 字段。

我遇到的问题是,虽然 Preload 将数据插入 environments 字段,但在 Find 子句期间它似乎不可用:

var secrets []models.Secretif 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)

登录后复制

简而言之,我正在尝试编写此查询:在“secrets”表中,查找拥有这些秘密的匹配 userId,并查看秘密中关联的“environments.id”字段以查找匹配的 UUID特定环境 UUID(它也将由该用户拥有)。

例如,如果我使用此 92a4c405-f4f7-44d9-92df-76bd8a9ac3a6 用户 UUID 查询 secrets 以检查所有权,并使用此 cff8d599-3822-474d-a980-fb054fb9 进行查询23cc环境UUID,那么结果输出应该看起来像…

[    {        "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]

登录后复制

是否有一个 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) rWHERE 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 查询多位字段的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2484329.html

(0)
上一篇 2025年3月4日 21:31:29
下一篇 2025年3月4日 21:32:02

AD推荐 黄金广告位招租... 更多推荐

相关推荐

发表回复

登录后才能评论