1. Introdução às Operações de Entidades ent
Este tutorial irá guiá-lo de forma abrangente para dominar as operações de entidades no framework ent
, cobrindo o processo completo de criação, consulta, atualização e exclusão de entidades. É adequado para iniciantes mergulharem gradualmente na funcionalidade central do ent
.
3. Operação de Criação de Entidades
3.1 Criação de uma Única Entidade
Criar uma entidade é a operação fundamental para persistência de dados. Abaixo estão os passos para criar um único objeto de entidade usando o framework ent
e salvá-lo no banco de dados:
- Primeiro, defina a estrutura e os campos de uma entidade, ou seja, defina o modelo da entidade no arquivo
schema
. - Execute o comando
ent generate
para gerar o código de operação de entidade correspondente. - Use o método
Create
gerado para construir uma nova entidade e definir os valores dos campos da entidade por meio de chamadas encadeadas. - Por fim, chame o método
Save
para salvar a entidade no banco de dados.
O exemplo a seguir demonstra como criar e salvar uma entidade de usuário:
package main
import (
"context"
"log"
"entdemo/ent"
)
func main() {
// Crie uma instância do Cliente para interação com o banco de dados
cliente, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
if err != nil {
log.Fatalf("Falha ao abrir a conexão com o banco de dados: %v", err)
}
defer cliente.Close()
// Crie um contexto
ctx := context.Background()
// Crie uma entidade de usuário usando o Cliente
a8m, err := cliente.User.
Create().
SetName("a8m").
Save(ctx)
if err != nil {
log.Fatalf("Falha ao criar a entidade de usuário: %v", err)
}
// Entidade salva com sucesso no banco de dados
log.Printf("Entidade de usuário salva: %v", a8m)
}
Neste exemplo, um cliente de banco de dados cliente
é criado primeiro. Em seguida, o método User.Create
é usado para definir os atributos do novo usuário e, por fim, o método Save
é chamado para salvar o usuário no banco de dados.
3.2 Criação em Lote de Entidades
Em certos cenários, pode haver a necessidade de criar múltiplas entidades, como durante a inicialização do banco de dados ou operações de importação em massa de dados. O framework ent
fornece a capacidade de criar entidades em lotes, oferecendo melhor desempenho em comparação com a criação e salvamento de entidades individualmente.
Os passos para a criação em lote de entidades são os seguintes:
- Use o método
CreateBulk
em vez do métodoCreate
, o qual permite a criação de múltiplas entidades em uma única operação. - Chame
Create
para cada entidade a ser criada. - Uma vez que todas as entidades tenham sido criadas, use o método
Save
para salvá-las no banco de dados em lote.
Aqui está um exemplo de criação em lote de entidades:
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("Falha ao abrir a conexão com o banco de dados: %v", err)
}
defer cliente.Close()
ctx := context.Background()
// Crie em lote entidades Pet
pets, 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("Falha ao criar em lote as entidades Pet: %v", err)
}
log.Printf("Criadas %d entidades Pet em lote\n", len(pets))
}
Neste exemplo, um cliente
é criado primeiro e, em seguida, várias entidades Pet
são construídas usando o método CreateBulk
, definindo seus nomes e campos de proprietário. Todas as entidades são salvas no banco de dados de uma vez quando o método Save
é chamado, proporcionando melhor desempenho para lidar com grandes quantidades de dados.
4.1 Consulta Básica
A consulta de banco de dados é a forma fundamental de recuperar informações. Em ent
, o método Query
é usado para iniciar uma consulta. Abaixo estão os passos e um exemplo de consulta básica de entidades:
- Verifique se você tem uma instância utilizável de
Client
. - Use
Client.Query()
ou os métodos auxiliares da entidade comoPet.Query()
para criar uma consulta. - Adicione condições de filtragem conforme necessário, como
Where
. - Execute a consulta e recupere os resultados chamando o método
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("Falha ao abrir a conexão com o banco de dados: %v", err)
}
defer client.Close()
ctx := context.Background()
// Consultar todos os usuários com o nome "a8m"
users, err := client.User.
Query().
Where(user.NameEQ("a8m")).
All(ctx)
if err != nil {
log.Fatalf("Falha ao consultar os usuários: %v", err)
}
for _, u := range users {
log.Printf("Usuário encontrado: %#v\n", u)
}
}
Este exemplo demonstra como encontrar todos os usuários com o nome "a8m".
4.2 Paginação e Ordenação
A paginação e ordenação são recursos avançados comumente utilizados ao consultar, usados para controlar a ordem de saída e a quantidade de dados. Veja como realizar consultas de paginação e ordenação usando ent
:
- Use o método
Limit
para definir o número máximo de resultados a serem retornados. - Use o método
Offset
para pular alguns dos resultados anteriores. - Use o método
Order
para especificar o campo de ordenação e a direção.
Aqui está um exemplo de consulta de paginação e ordenação:
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("Falha ao abrir a conexão com o banco de dados: %v", err)
}
defer client.Close()
ctx := context.Background()
// Consultar Pets em ordem decrescente de idade com paginação
pets, err := client.Pet.
Query().
Order(ent.Desc(pet.FieldAge)).
Limit(10).
Offset(0).
All(ctx)
if err != nil {
log.Fatalf("Falha ao consultar Pets: %v", err)
}
for _, p := range pets {
log.Printf("Pet encontrado: %#v\n", p)
}
}
Este exemplo demonstra como recuperar a primeira página, até 10 registros, de pets ordenados em ordem decrescente por idade. Ao modificar os valores de Limit
e Offset
, é possível fazer a paginação por todo o conjunto de dados.
5. Operações de Atualização da Entidade
5.1 Atualizando uma Única Entidade
Em muitas aplicações, a atualização de entidades é uma parte essencial das operações diárias. Nesta seção, vamos demonstrar como usar o framework Ent para atualizar uma única entidade no banco de dados.
Primeiramente, assumindo que precisamos atualizar a idade de um usuário, podemos utilizar o método Update
gerado pelo Ent.
// Considerando que já temos uma entidade de usuário 'a8m' e um contexto 'ctx'
a8m, err := a8m.Update(). // Criar um construtor de atualização de usuário
SetAge(30). // Definir a idade do usuário para 30 anos
Save(ctx) // Realizar a operação de salvamento e retornar o resultado
if err != nil {
log.Fatalf("Falha ao atualizar o usuário: %v", err)
}
Também é possível atualizar vários campos simultaneamente:
a8m, err := a8m.Update().
SetAge(30). // Atualizar idade
SetName("Ariel"). // Atualizar nome
AddRank(10). // Aumentar a classificação em 10
Save(ctx)
if err != nil {
log.Fatalf("Falha ao atualizar o usuário: %v", err)
}
A operação de atualização pode ser encadeada, o que é muito flexível e fácil de ler. Chamar o método Save
irá realizar a atualização e retornar a entidade atualizada ou uma mensagem de erro.
5.2 Atualizações Condicionais
Ent permite que você faça atualizações baseadas em condições. Aqui está um exemplo onde apenas usuários que atendam a condições específicas serão atualizados.
// Supondo que temos o `id` de um usuário e queremos marcá-lo como concluído para a versão `currentVersion`
err := client.Todo.
UpdateOneID(id). // Cria um construtor para atualizar pelo ID do usuário
SetStatus(todo.StatusDone).
AddVersion(1).
Where(
todo.Version(currentVersion), // A operação de atualização é executada apenas quando a versão atual corresponder
).
Exec(ctx)
switch {
case ent.IsNotFound(err):
fmt.Println("Tarefa não encontrada")
case err != nil:
fmt.Println("Erro na atualização:", err)
}
Ao utilizar atualizações condicionais, o método .Where()
deve estar envolvido. Isso permite que você determine se a atualização deve ser realizada com base nos valores atuais no banco de dados, o que é crucial para garantir a consistência e integridade dos dados.
6. Operações de Exclusão de Entidades
6.1 Excluindo uma Única Entidade
Excluir entidades é outra função importante em operações de banco de dados. A estrutura Ent fornece uma API simples para realizar operações de exclusão.
O exemplo a seguir demonstra como excluir uma entidade de usuário específica:
err := client.User.
DeleteOne(a8m). // Cria um construtor de exclusão de usuário
Exec(ctx) // Executa a operação de exclusão
if err != nil {
log.Fatalf("Falha ao excluir usuário: %v", err)
}
6.2 Exclusão Condicional
Assim como as operações de atualização, também podemos realizar operações de exclusão com base em condições específicas. Em certos cenários, podemos querer excluir apenas entidades que atendam a condições específicas. O uso do método .Where()
pode definir essas condições:
// Suponha que desejamos excluir todos os arquivos com uma data de atualização anterior a uma determinada data
afetados, err := client.File.
Delete().
Where(file.UpdatedAtLT(date)). // Execute a exclusão apenas se o tempo de atualização do arquivo for anterior à data fornecida
Exec(ctx)
if err != nil {
log.Fatalf("Falha ao excluir arquivos: %v", err)
}
// Esta operação retorna o número de registros afetados pela operação de exclusão
fmt.Printf("%d arquivos foram excluídos\n", afetados)
O uso de operações de exclusão condicionais garante controle preciso sobre nossas operações de dados, garantindo que apenas entidades que realmente atendam às condições sejam excluídas. Isso aprimora a segurança e confiabilidade das operações de banco de dados.