In der PHP-Entwicklung sind Datenbankoperationen sehr häufige Aufgaben. Bei Datenbankoperationen ist die Abfrage mehrerer Felder eine häufige Anforderung. Als Reaktion auf diese Nachfrage ist go-gorm eine leistungsstarke ORM-Bibliothek, die Entwicklern dabei helfen kann, mehrere Felder schnell und effizient abzufragen. In diesem Artikel stellt der PHP-Editor Xinyi vor, wie mehrere Felder in go-gorm abgefragt werden, und gibt entsprechenden Beispielcode, der Ihnen hilft, diese Technik leicht zu beherrschen. Ganz gleich, ob Sie Anfänger oder erfahrener Entwickler sind, dieser Artikel kann Ihnen wertvolle Hilfe und Anleitung bieten. Lass uns einen Blick darauf werfen!
Ich habe folgende Modelle:
<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>
Wenn Sie ein Geheimnis mit einer oder mehreren Umgebungen erstellen, erstellt die environment_secrets
-Tabelle eine oder mehrere Zeilen basierend darauf, wie viele Umgebungen dasselbe Geheimnis teilen:
secret_id | environment_id -------------------------- uuid | uuid
Was ich tun möchte, ist das Feld secrets
表中的 environments
abzufragen.
Das Problem, das ich habe, ist, dass es während der Preload
将数据插入 environments
字段,但在 Find
-Klausel anscheinend nicht verfügbar ist:
<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>
Kurz gesagt, ich versuche, diese Abfrage zu schreiben: 在“secrets”表中,查找拥有这些秘密的匹配 userId,并查看秘密中关联的“environments.id”字段以查找匹配的 UUID特定环境 UUID(它也将由该用户拥有)
.
Wenn ich zum Beispiel diese 92a4c405-f4f7-44d9-92df-76bd8a9ac3a6
用户 UUID 查询 secrets
以检查所有权,并使用此 cff8d599-3822-474d-a980-fb054fb9 进行查询23cc
Umgebungs-UUID verwende, sollte die resultierende Ausgabe so aussehen...
<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>
Gibt es eine JOIN-Abfrage oder vielleicht eine reine SQL-Abfrage, die ich schreiben kann, um sie in environments
行数据在 secrets
für die Abfrage verfügbar zu machen?
ist nicht schön, aber diese grobe GORM-SQL-Abfrage funktioniert wie erwartet:
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 @> ?;
Abfrage kann verstanden werden als...
Aggregieren Sie Geheimnisse in r
(结果),其中 environments
Feldern mit:
Von r
(结果)中查找 environments
JSON 数组中的部分参数化 id
.
Und einige Beispiele für Go-Code mit 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) }
Das obige ist der detaillierte Inhalt vongo-gorm fragt Multi-Bit-Felder ab. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!