1. Introduction aux opérations d'entité ent
Ce tutoriel vous guidera de manière exhaustive dans la maîtrise des opérations d'entité dans le framework ent
, couvrant l'ensemble du processus de création, de requête, de mise à jour et de suppression d'entités. Il convient aux débutants pour plonger progressivement dans les fonctionnalités essentielles de ent
.
3. Opération de création d'entité
3.1 Création d'une seule entité
La création d'une entité est l'opération fondamentale pour la persistance des données. Voici les étapes pour créer un seul objet entité en utilisant le framework ent
et le sauvegarder dans la base de données:
- Tout d'abord, définissez la structure et les champs d'une entité, c'est-à-dire définissez le modèle de l'entité dans le fichier
schema
. - Exécutez la commande
ent generate
pour générer le code d'opération d'entité correspondant. - Utilisez la méthode
Create
générée pour construire une nouvelle entité, et définissez les valeurs des champs de l'entité à travers des appels enchaînés. - Enfin, appelez la méthode
Save
pour sauvegarder l'entité dans la base de données.
L'exemple suivant démontre comment créer et sauvegarder une entité utilisateur :
package main
import (
"context"
"log"
"entdemo/ent"
)
func main() {
// Créer une instance Client pour interagir avec la base de données
client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
if err != nil {
log.Fatalf("Impossible d'ouvrir la connexion à la base de données: %v", err)
}
defer client.Close()
// Créer un contexte
ctx := context.Background()
// Créer une entité utilisateur en utilisant le Client
a8m, err := client.User.
Create().
SetName("a8m").
Save(ctx)
if err != nil {
log.Fatalf("Impossible de créer l'entité utilisateur: %v", err)
}
// Entité sauvegardée avec succès dans la base de données
log.Printf("Entité utilisateur sauvegardée: %v", a8m)
}
Dans cet exemple, un client de base de données client
est créé en premier. Ensuite, la méthode User.Create
est utilisée pour définir les attributs du nouvel utilisateur, et enfin, la méthode Save
est appelée pour sauvegarder l'utilisateur dans la base de données.
3.2 Création d'entité en lot
Dans certains scénarios, il peut être nécessaire de créer plusieurs entités, comme lors de l'initialisation de la base de données ou des opérations d'importation de données en masse. Le framework ent
offre la possibilité de créer des entités en lots, ce qui offre de meilleures performances par rapport à la création et à la sauvegarde d'entités individuellement.
Les étapes pour la création d'entité en lot sont les suivantes :
- Utilisez la méthode
CreateBulk
au lieu de la méthodeCreate
, qui permet la création de multiples entités en une seule opération. - Appelez
Create
pour chaque entité à créer. - Une fois que toutes les entités ont été créées, utilisez la méthode
Save
pour sauvegarder les entités dans la base de données en lot.
Voici un exemple de création d'entité en lot :
package main
import (
"context"
"log"
"entdemo/ent"
)
func main() {
client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
if err != nil {
log.Fatalf("Impossible d'ouvrir la connexion à la base de données: %v", err)
}
defer client.Close()
ctx := context.Background()
// Créer en lot des entités Pet
pets, err := client.Pet.CreateBulk(
client.Pet.Create().SetName("pedro").SetOwner(a8m),
client.Pet.Create().SetName("xabi").SetOwner(a8m),
client.Pet.Create().SetName("layla").SetOwner(a8m),
).Save(ctx)
if err != nil {
log.Fatalf("Impossible de créer en lot des entités Pet: %v", err)
}
log.Printf("Création de %d entités Pet en lot\n", len(pets))
}
Dans cet exemple, un client
est créé en premier, puis plusieurs entités Pet
sont construites en utilisant la méthode CreateBulk
, définissant leurs noms et champs propriétaire. Toutes les entités sont sauvegardées dans la base de données en une seule fois lorsque la méthode Save
est appelée, offrant de meilleures performances pour la gestion de grandes quantités de données.
4. Opérations de requête d'entité
4.1 Requête de base
Interroger la base de données est le moyen fondamental de récupérer des informations. Dans ent
, la méthode Query
est utilisée pour démarrer une requête. Voici les étapes et un exemple de requête d'entité de base :
- Assurez-vous d'avoir une instance utilisable de
Client
. - Utilisez
Client.Query()
ou les méthodes d'aide d'entité telles quePet.Query()
pour créer une requête. - Ajoutez les conditions de filtrage selon les besoins, telles que
Where
. - Exécutez la requête et récupérez les résultats en appelant la méthode
All
.
package main
import (
"context"
"log"
"entdemo/ent"
"entdemo/ent/user"
)
func main() {
client, err := ent.Open("sqlite3", "file:ent?cache=shared&_fk=1")
if err != nil {
log.Fatalf("Échec de l'ouverture de la connexion à la base de données : %v", err)
}
defer client.Close()
ctx := context.Background()
// Requête de tous les utilisateurs nommés "a8m"
users, err := client.User.
Query().
Where(user.NameEQ("a8m")).
All(ctx)
if err != nil {
log.Fatalf("Échec de la requête des utilisateurs : %v", err)
}
for _, u := range users {
log.Printf("Utilisateur trouvé : %#v\n", u)
}
}
Cet exemple démontre comment trouver tous les utilisateurs avec le nom "a8m".
4.2 Pagination et Tri
La pagination et le tri sont des fonctionnalités avancées couramment utilisées lors des requêtes, utilisées pour contrôler l'ordre de sortie et la quantité de données. Voici comment réaliser des requêtes de pagination et de tri à l'aide de ent
:
- Utilisez la méthode
Limit
pour définir le nombre maximal de résultats à renvoyer. - Utilisez la méthode
Offset
pour sauter certains des résultats précédents. - Utilisez la méthode
Order
pour spécifier le champ de tri et la direction.
Voici un exemple de requête de pagination et de tri :
package main
import (
"context"
"log"
"entdemo/ent"
"entdemo/ent/pet"
)
func main() {
client, err := ent.Open("sqlite3", "file:ent?cache=shared&_fk=1")
if err != nil {
log.Fatalf("Échec de l'ouverture de la connexion à la base de données : %v", err)
}
defer client.Close()
ctx := context.Background()
// Requête des animaux de compagnie dans l'ordre décroissant de l'âge avec pagination
pets, err := client.Pet.
Query().
Order(ent.Desc(pet.FieldAge)).
Limit(10).
Offset(0).
All(ctx)
if err != nil {
log.Fatalf("Échec de la requête des animaux de compagnie : %v", err)
}
for _, p := range pets {
log.Printf("Animal de compagnie trouvé : %#v\n", p)
}
}
Cet exemple démontre comment récupérer la première page, jusqu'à 10 enregistrements, d'animaux de compagnie triés par ordre décroissant d'âge. En modifiant les valeurs de Limit
et Offset
, vous pouvez effectuer la pagination de l'ensemble des données.
5. Opérations de mise à jour d'entité
5.1 Mise à jour d'une seule entité
Dans de nombreuses applications, la mise à jour des entités est une partie essentielle des opérations quotidiennes. Dans cette section, nous allons démontrer comment utiliser le framework Ent pour mettre à jour une seule entité dans la base de données.
Tout d'abord, supposons que nous devons mettre à jour l'âge d'un utilisateur, nous pouvons utiliser la méthode Update
générée par Ent.
// En supposant que nous avons déjà une entité utilisateur 'a8m' et un contexte 'ctx'
a8m, err := a8m.Update(). // Créer un constructeur de mise à jour d'utilisateur
SetAge(30). // Définir l'âge de l'utilisateur à 30 ans
Save(ctx) // Effectuer l'opération de sauvegarde et retourner le résultat
if err != nil {
log.Fatalf("Échec de la mise à jour de l'utilisateur : %v", err)
}
Vous pouvez également mettre à jour plusieurs champs simultanément :
a8m, err := a8m.Update().
SetAge(30). // Mettre à jour l'âge
SetName("Ariel"). // Mettre à jour le nom
AddRank(10). // Augmenter le rang de 10
Save(ctx)
if err != nil {
log.Fatalf("Échec de la mise à jour de l'utilisateur : %v", err)
}
L'opération de mise à jour peut être chaînée, ce qui est très flexible et facile à lire. L'appel de la méthode Save
effectuera la mise à jour et renverra l'entité mise à jour ou un message d'erreur.
5.2 Mises à jour conditionnelles
Ent vous permet d'effectuer des mises à jour basées sur des conditions. Voici un exemple où seuls les utilisateurs répondant à des conditions spécifiques seront mis à jour.
// Supposons que nous avons l'`id` d'un utilisateur et que nous voulons marquer cet utilisateur comme étant terminé pour la version `currentVersion`
err := client.Todo.
UpdateOneID(id). // Créer un constructeur pour la mise à jour par ID utilisateur
SetStatus(todo.StatusDone).
AddVersion(1).
Where(
todo.Version(currentVersion), // L'opération de mise à jour est uniquement exécutée lorsque la version actuelle correspond
).
Exec(ctx)
switch {
case ent.IsNotFound(err):
fmt.Println("Todo non trouvé")
case err != nil:
fmt.Println("Erreur de mise à jour :", err)
}
Lors de l'utilisation de mises à jour conditionnelles, la méthode .Where()
doit être impliquée. Cela vous permet de déterminer si la mise à jour doit être effectuée en fonction des valeurs actuelles dans la base de données, ce qui est crucial pour garantir la cohérence et l'intégrité des données.
6. Opérations de suppression d'entité
6.1 Suppression d'une seule entité
La suppression d'entités est une autre fonction importante dans les opérations de base de données. Le framework Ent fournit une API simple pour effectuer des opérations de suppression.
L'exemple suivant montre comment supprimer une entité utilisateur donnée :
err := client.User.
DeleteOne(a8m). // Créer un constructeur de suppression d'utilisateur
Exec(ctx) // Exécuter l'opération de suppression
if err != nil {
log.Fatalf("Échec de la suppression de l'utilisateur : %v", err)
}
6.2 Suppression conditionnelle
Tout comme les opérations de mise à jour, nous pouvons également effectuer des opérations de suppression basées sur des conditions spécifiques. Dans certains scénarios, nous ne voulons peut-être supprimer que des entités répondant à des conditions spécifiques. L'utilisation de la méthode .Where()
permet de définir ces conditions :
// Supposons que nous voulons supprimer tous les fichiers dont l'heure de mise à jour est antérieure à une certaine date
affected, err := client.File.
Delete().
Where(file.UpdatedAtLT(date)). // N'exécutez la suppression que si l'heure de mise à jour du fichier est antérieure à la date donnée
Exec(ctx)
if err != nil {
log.Fatalf("Échec de la suppression des fichiers : %v", err)
}
// Cette opération renvoie le nombre d'enregistrements touchés par l'opération de suppression
fmt.Printf("%d fichiers ont été supprimés\n", affected)
L'utilisation d'opérations de suppression conditionnelles assure un contrôle précis sur nos opérations de données, garantissant que seules les entités répondant véritablement aux conditions sont supprimées. Cela améliore la sécurité et la fiabilité des opérations de base de données.