Rumah  >  Artikel  >  pembangunan bahagian belakang  >  go-gorm menanyakan medan berbilang bit

go-gorm menanyakan medan berbilang bit

王林
王林ke hadapan
2024-02-09 20:03:09658semak imbas

go-gorm 查询多位字段

Dalam pembangunan PHP, operasi pangkalan data adalah tugas yang sangat biasa. Dalam operasi pangkalan data, menanyakan berbilang medan adalah keperluan biasa. Sebagai tindak balas kepada permintaan ini, go-gorm ialah perpustakaan ORM yang berkuasa yang boleh membantu pembangun menanyakan berbilang medan dengan cepat dan cekap. Dalam artikel ini, editor PHP Xinyi akan memperkenalkan cara membuat pertanyaan berbilang medan dalam go-gorm, dan memberikan kod sampel yang sepadan untuk membantu anda menguasai teknik ini dengan mudah. Sama ada anda seorang pemula atau pembangun yang berpengalaman, artikel ini boleh memberi anda bantuan dan bimbingan yang berharga. Mari lihat!

Kandungan soalan

Saya mempunyai model berikut:

<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>

Apabila anda mencipta rahsia dengan satu atau lebih persekitaran, jadual environment_secrets mencipta satu atau lebih baris berdasarkan bilangan persekitaran yang berkongsi rahsia yang sama:

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

Apa yang saya mahu lakukan ialah menanyakan medan secrets 表中的 environments.

Masalah yang saya hadapi ialah ia nampaknya tidak tersedia semasa klausa Preload 将数据插入 environments 字段,但在 Find walaupun:

<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>

Ringkasnya, saya cuba menulis pertanyaan ini: 在“secrets”表中,查找拥有这些秘密的匹配 userId,并查看秘密中关联的“environments.id”字段以查找匹配的 UUID特定环境 UUID(它也将由该用户拥有).

Sebagai contoh, jika saya menggunakan 92a4c405-f4f7-44d9-92df-76bd8a9ac3a6 用户 UUID 查询 secrets 以检查所有权,并使用此 cff8d599-3822-474d-a980-fb054fb9 进行查询23ccUID Persekitaran ini, maka output yang terhasil sepatutnya kelihatan seperti...

<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>

Adakah terdapat pertanyaan JOIN atau mungkin pertanyaan SQL mentah yang boleh saya tulis untuk disediakan dalam environments 行数据在 secrets untuk pertanyaan?

Penyelesaian

tidak cantik, tetapi pertanyaan GORM SQL anjing mentah ini berfungsi seperti yang diharapkan:

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 @> ?;

Pertanyaan boleh difahami sebagai...

Agregat rahsia ke dalam r (结果),其中 environments medan dengan:

  • ID Rahsia yang sepadan dengan berbilang pasang ID rahsia jadual
  • ID persekitaran padanan ID persekitaran berbilang jadual
  • Dan tapis berdasarkan ID pengguna rahsia padanan parameter ID pengguna

Dari r (结果)中查找 environments JSON 数组中的部分参数化 id.

Dan beberapa contoh kod Go menggunakan go Fiber:

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)
}

Atas ialah kandungan terperinci go-gorm menanyakan medan berbilang bit. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam