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!
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 进行查询23cc
UID 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?
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:
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!