1. Introducción a las operaciones de entidades en ent
Este tutorial te guiará de forma exhaustiva para dominar las operaciones de entidades en el marco de trabajo ent
, abarcando el proceso completo de creación, consulta, actualización y eliminación de entidades. Es adecuado para principiantes que desean adentrarse gradualmente en la funcionalidad central de ent
.
3. Operación de Creación de Entidades
3.1 Creación de una sola entidad
Crear una entidad es la operación fundamental para la persistencia de datos. A continuación se detallan los pasos para crear un objeto de entidad único utilizando el marco de trabajo ent
y guardarlo en la base de datos:
- En primer lugar, define la estructura y campos de una entidad, es decir, define el modelo de la entidad en el archivo de
schema
. - Ejecuta el comando
ent generate
para generar el código de operación de entidad correspondiente. - Utiliza el método
Create
generado para construir una nueva entidad y establecer los valores de campo de la entidad mediante llamadas encadenadas. - Finalmente, llama al método
Save
para guardar la entidad en la base de datos.
A continuación se muestra un ejemplo que demuestra cómo crear y guardar una entidad de usuario:
package main
import (
"context"
"log"
"entdemo/ent"
)
func main() {
// Crea una instancia de Cliente para la interacción con la base de datos
cliente, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
if err != nil {
log.Fatalf("Error al abrir la conexión a la base de datos: %v", err)
}
defer cliente.Close()
// Crea un contexto
ctx := context.Background()
// Crea una entidad de usuario utilizando el Cliente
a8m, err := cliente.User.
Create().
SetName("a8m").
Save(ctx)
if err != nil {
log.Fatalf("Error al crear la entidad de usuario: %v", err)
}
// Entidad guardada con éxito en la base de datos
log.Printf("Entidad de usuario guardada: %v", a8m)
}
En este ejemplo, se crea primero un cliente de base de datos cliente
. Luego, se utiliza el método User.Create
para establecer los atributos del nuevo usuario y, finalmente, se llama al método Save
para guardar al usuario en la base de datos.
3.2 Creación de Entidades en Lote
En ciertos escenarios, puede ser necesario crear múltiples entidades, como durante la inicialización de la base de datos o operaciones de importación masiva de datos. El marco de trabajo ent
proporciona la capacidad de crear entidades en lotes, lo que ofrece un mejor rendimiento en comparación con la creación y guardado de entidades de forma individual.
Los pasos para la creación de entidades en lotes son los siguientes:
- Utiliza el método
CreateBulk
en lugar del métodoCreate
, que permite la creación de múltiples entidades en una sola operación. - Llama a
Create
para cada entidad que se va a crear. - Una vez que se han creado todas las entidades, utiliza el método
Save
para guardar las entidades en la base de datos de forma masiva.
A continuación se muestra un ejemplo de creación de entidades en lotes:
package main
import (
"context"
"log"
"entdemo/ent"
)
func main() {
cliente, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
if err != nil {
log.Fatalf("Error al abrir la conexión a la base de datos: %v", err)
}
defer cliente.Close()
ctx := context.Background()
// Crear entidades de Mascota en lotes
mascotas, err := cliente.Pet.CreateBulk(
cliente.Pet.Create().SetName("pedro").SetOwner(a8m),
cliente.Pet.Create().SetName("xabi").SetOwner(a8m),
cliente.Pet.Create().SetName("layla").SetOwner(a8m),
).Save(ctx)
if err != nil {
log.Fatalf("Error al crear entidades de Mascota en lotes: %v", err)
}
log.Printf("Se crearon %d entidades de Mascota en lote\n", len(mascotas))
}
En este ejemplo, se crea primero un cliente
, y luego se construyen múltiples entidades de Pet
utilizando el método CreateBulk
, estableciendo sus nombres y campos de propietario. Todas las entidades se guardan en la base de datos a la vez cuando se llama al método Save
, lo que proporciona un mejor rendimiento para manejar grandes cantidades de datos.
4. Operaciones de Consulta de Entidades
4.1 Consulta básica
La consulta de base de datos es la forma fundamental de recuperar información. En ent
, el método Query
se utiliza para iniciar una consulta. A continuación se presentan los pasos y un ejemplo de consulta básica de entidades:
- Asegúrese de tener una instancia utilizable de
Client
. - Utilice
Client.Query()
o métodos auxiliares de entidad comoPet.Query()
para crear una consulta. - Agregue condiciones de filtrado según sea necesario, como
Where
. - Ejecute la consulta y recupere los resultados llamando al método
All
.
paquete principal
import (
"context"
"registrar"
"entdemo/ent"
"entdemo/ent/user"
)
func main() {
cliente, err := ent.Open("sqlite3", "archivo:ent?cache=shared&_fk=1")
if err != nil {
log.Fatalf("Error al abrir la conexión a la base de datos: %v", err)
}
defer cliente.Close()
ctx := context.Background()
// Consulta de todos los usuarios con el nombre "a8m"
usuarios, err := cliente.User.
Query().
Where(user.NameEQ("a8m")).
All(ctx)
if err != nil {
log.Fatalf("Error al consultar usuarios: %v", err)
}
para _, u := rango usuarios {
log.Printf("Usuario encontrado: %#v\n", u)
}
}
Este ejemplo demuestra cómo encontrar todos los usuarios con el nombre "a8m".
4.2 Paginación y ordenación
La paginación y la ordenación son características avanzadas comúnmente utilizadas al realizar consultas, y se utilizan para controlar el orden y la cantidad de datos de salida. Así es como se logra la paginación y las consultas de ordenación utilizando ent
:
- Utilice el método
Limit
para establecer el número máximo de resultados que se devolverán. - Utilice el método
Offset
para omitir algunos de los resultados anteriores. - Utilice el método
Order
para especificar el campo de ordenación y la dirección.
Aquí hay un ejemplo de una consulta de paginación y ordenación:
paquete principal
import (
"context"
"registrar"
"entdemo/ent"
"entdemo/ent/pet"
)
func main() {
cliente, err := ent.Open("sqlite3", "archivo:ent?cache=shared&_fk=1")
if err != nil {
log.Fatalf("Error al abrir la conexión a la base de datos: %v", err)
}
defer cliente.Close()
ctx := context.Background()
// Consulta de mascotas en orden descendente por edad con paginación
mascotas, err := cliente.Pet.
Query().
Order(ent.Desc(pet.FieldAge)).
Limit(10).
Offset(0).
All(ctx)
if err != nil {
log.Fatalf("Error al consultar mascotas: %v", err)
}
para _, p := rango mascotas {
log.Printf("Mascota encontrada: %#v\n", p)
}
}
Este ejemplo demuestra cómo recuperar la primera página, hasta 10 registros, de mascotas ordenadas en orden descendente por edad. Al modificar los valores de Limit
y Offset
, se puede lograr la paginación a través del conjunto de datos completo.
5. Operaciones de actualización de entidad
5.1 Actualización de una sola entidad
En muchas aplicaciones, la actualización de entidades es una parte esencial de las operaciones diarias. En esta sección, demostraremos cómo utilizar el marco Ent para actualizar una sola entidad en la base de datos.
En primer lugar, suponiendo que necesitamos actualizar la edad de un usuario, podemos utilizar el método Update
generado por Ent.
// Suponiendo que ya tenemos una entidad de usuario 'a8m' y un contexto 'ctx'
a8m, err := a8m.Update(). // Crea un constructor de actualización de usuario
SetAge(30). // Establece la edad del usuario en 30 años
Save(ctx) // Realiza la operación de guardado y devuelve el resultado
if err != nil {
log.Fatalf("Error al actualizar el usuario: %v", err)
}
También se pueden actualizar varios campos simultáneamente:
a8m, err := a8m.Update().
SetAge(30). // Actualizar la edad
SetName("Ariel"). // Actualizar el nombre
AddRank(10). // Aumentar el rango en 10
Save(ctx)
if err != nil {
log.Fatalf("Error al actualizar el usuario: %v", err)
}
La operación de actualización se puede encadenar, lo que es muy flexible y fácil de leer. Llamar al método Save
realizará la actualización y devolverá la entidad actualizada o un mensaje de error.
5.2 Actualizaciones Condicionales
Ent te permite realizar actualizaciones basadas en condiciones. Aquí tienes un ejemplo en el que solo se actualizarán los usuarios que cumplan condiciones específicas.
// Suponiendo que tenemos el `id` de un usuario y queremos marcar ese usuario como completado para la versión `currentVersion`
err := client.Todo.
UpdateOneID(id). // Crea un constructor para actualizar por ID de usuario
SetStatus(todo.StatusDone).
AddVersion(1).
Where(
todo.Version(currentVersion), // La operación de actualización solo se ejecuta cuando la versión actual coincide
).
Exec(ctx)
switch {
case ent.IsNotFound(err):
fmt.Println("Tarea no encontrada")
case err != nil:
fmt.Println("Error al actualizar:", err)
}
Al utilizar actualizaciones condicionales, el método .Where()
debe estar involucrado. Esto te permite determinar si la actualización debe realizarse en función de los valores actuales en la base de datos, lo cual es crucial para garantizar la consistencia e integridad de los datos.
6. Operaciones de Eliminación de Entidades
6.1 Eliminación de una Única Entidad
Eliminar entidades es otra función importante en las operaciones de base de datos. El framework Ent proporciona una API sencilla para realizar operaciones de eliminación.
El siguiente ejemplo demuestra cómo eliminar una entidad de usuario específica:
err := client.User.
DeleteOne(a8m). // Crea un constructor de eliminación de usuario
Exec(ctx) // Ejecuta la operación de eliminación
if err != nil {
log.Fatalf("Error al eliminar el usuario: %v", err)
}
6.2 Eliminación Condicional
Al igual que con las operaciones de actualización, también podemos realizar operaciones de eliminación basadas en condiciones específicas. En ciertos escenarios, es posible que solo queramos eliminar entidades que cumplan condiciones específicas. El uso del método .Where()
puede definir estas condiciones:
// Supongamos que queremos eliminar todos los archivos con una fecha de actualización anterior a una fecha específica
afectados, err := client.File.
Delete().
Where(file.UpdatedAtLT(date)). // Solo ejecutar la eliminación si la fecha de actualización del archivo es anterior a la fecha proporcionada
Exec(ctx)
if err != nil {
log.Fatalf("Error al eliminar archivos: %v", err)
}
// Esta operación devuelve el número de registros afectados por la operación de eliminación
fmt.Printf("%d archivos han sido eliminados\n", afectados)
El uso de operaciones de eliminación condicionales garantiza un control preciso sobre nuestras operaciones de datos, asegurando que solo se eliminen las entidades que realmente cumplan las condiciones. Esto mejora la seguridad y confiabilidad de las operaciones de base de datos.