GORM ORM - Mapeamento de objeto relacional em Go
O que o ORM faz?
O ORM é fornecido com construções especiais de abstração que podem ser usadas para criar consultas ao banco de dados. Em outras palavras, no lugar de realizar uma ação direta no banco de dados com código SQL, por exemplo, utilizamos o ORM como ponte de comunicação entre o banco de dados e a aplicação.
Existe um ORM para todas as linguagens?
As principais linguagens do mercado possuem ORM, já que essa técnica facilita muito a vida das pessoas que desenvolvem. A linguagem Java, por exemplo, possui o Hibernate, que é muito utilizado no mercado. No caso do C#, o Entity Framework, no Python temos o Django ORM e o SqlAlchemy. Mas qual é o ORM mais utilizado da linguagem Go?
Go e seus diferentes ORM's
Go (ou “Golang”) é uma linguagem de programação compilada inventada no Google por Robert Griesemer, Rob Pike e Ken Thompson. É uma linguagem de programação de código aberto que possui o objetivo de facilitar a construção de software de forma simples, confiável e eficiente.
No Go, existem diferentes ORM's, porém alguns são mais utilizados no mercado, como GORM, Go PG e o GORP. Neste artigo, vamos focar em abordar o GORM.
O que é Gorm?
Gorm é um ORM que facilita e acelera o desenvolvimento de software com Go. Ele auxilia na realização de todas as operações do CRUD (criar, ler, atualizar, excluir registros) e permite diferentes tipos de associações entre os modelos. Além disso, permite Transactions, SavePoint e RollbackTo para salvar e reverter alterações no banco de dados, migrações automáticas, e múltiplos bancos de dados no mesmo projeto. Para mais detalhes, veja a documentação oficial neste link.
Exemplo prático
Que tal botar a mão na massa e ver como esse ORM funciona de verdade? Para isso, verifique a versão do Go instalada em sua máquina, abrindo o Prompt ou terminal e digitando o seguinte comando:
go version
Até o momento deste artigo, minha versão do Go é:
go version go1.17.1 linux/amd64
Caso não tenha o Go instalado, veja nesse link o passo a passo para instalar de acordo com o seu sistema operacional.
Agora, crie uma pasta vazia, abra em seu editor de código preferido, e inicie um projeto Go com o seguinte comando:
go mod init github.com/MurilloGodoi/orm-go
Dica: No lugar de github.com/MurilloGodoi/orm-go, inclua seu repositório com o nome que desejar.
Instalação do Gorm
Vamos instalar o Gorm com o seguinte comando:
go get -u gorm.io/gorm
O Gorm suporta oficialmente diferentes bancos de dados, como MySQL, PostgreSQL, SQLite, e SQL Server. Neste exemplo, vamos utilizar o SQLite. Para isso, vamos instalar seu respectivo driver:
go get -u gorm.io/driver/sqlite
Criação do arquivo
Neste exemplo, iremos realizar um CRUD (criar, ler, atualizar, excluir registros) de cursos. Para isso, primeiramente, será preciso criar um arquivo chamado main.go, e neste arquivo vamos ter que declarar o package e as importações que serão utilizadas no projeto, desta forma:
package main
import (
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
Declarando o modelo do curso
Os cursos terão um nome, uma área do conhecimento e o nome do professor. A declaração do modelo a partir de uma struct será feita desta forma:
package main
type Curso struct {
Nome string
Area string
Professor string
}
Para que a struct de curso seja identificada e mapeada corretamente pelo GORM, teremos que adicionar o seguinte código dentro da struct:
gorm.Model
A struct completa deverá ficar assim:
type Curso struct {
gorm.Model
Nome string
Area string
Professor string
}
Conectando com o banco de dados
Agora, já podemos criar a função principal do nosso programa, e conectar nossa aplicação com o banco de dados.
As funções principais no Go são criadas com o seguinte código:
func main() { }
Com a função principal criada, a conexão com o banco de dados será feita utilizando a função Open do Gorm. Nesta função passaremos o banco de dados que será utilizado e as configurações do Gorm. Para passar o banco de dados que será utilizado, a função Open do módulo SQLite importada em nosso projeto nos ajudará com isso. Essa função abrirá nosso banco de dados SQLite e, para isso, como parâmetro desta função, passaremos o nome do banco de dados, que optei por chamá-lo de cursos.db.
Código da conexão com o banco de dados:
db, err := gorm.Open(sqlite.Open("cursos.db"), &gorm.Config{})
if err != nil {
panic("erro ao acessar o banco de dados")
}
Primeira migração
Para criar a tabela de cursos no banco de dados com propriedades iguais às da nossa struct, o método AutoMigrate do GORM deverá ser utilizado, passando o endereço de memória da nossa struct de cursos como parâmetro, desta forma:
db.AutoMigrate(&Product{})
O CRUD de cursos
Para realizar o CRUD, utilizaremos quatro funções básicas do GORM, sendo elas: a Create, que será utilizada para criar um novo curso no banco de dados, a First, para procurar o primeiro produto com o id igual ao fornecido por nós, a Update, para atualizar um curso que previamente está salvo no banco de dados, e, por fim, a Delete, para deletar um curso da base de dados. Então, vamos lá?
Criando um curso
Como dito anteriormente, para criar um novo curso utilizaremos a função Create, passando o endereço de memória do curso que será salvo no banco de dados. Fique a vontade para alterar os valores das propriedades da struct.
db.Create(&Curso{Nome: "Go: Fundamentos de uma aplicacao web", Area: "Programacao", Professor: "Guilherme Lima"})
Lendo um curso do banco de dados
Primeiramente, vamos criar uma variável chamada curso, que terá a tipagem da nossa struct de curso.
var curso Curso
Essa variável será utilizada para receber os valores referentes ao curso encontrado com o ID que passaremos. Para procurar um curso pelo ID, vamos utilizar a função First do GORM, deste modo:
db.First(&curso, 1)
Perceba que é preciso passar como parâmetro o endereço de memória da variável curso, para que seja realizada corretamente a cópia dos valores encontrados. E como segundo parâmetro o ID do curso que queremos procurar, neste caso, o curso com ID de valor 1.
Atualizando um curso do banco de dados
Para atualizar um curso, primeiro temos que encontrá-lo no banco de dados para saber se ele realmente existe. Fazemos isso seguindo os passos da leitura de um curso, como dito anteriormente.
var curso Curso
db.First(&curso, 1)
Supondo que o curso seja encontrado na nossa base de dados, utilizaremos a função update para atualizar o curso. Nesta função, podemos definir quais campos do curso que serão atualizados, passando o nome do campo e em seguida o novo valor. Será necessário também definir qual o curso que será atualizado e a função Model do GORM nos ajudará com isso. Teremos apenas que passar como parâmetro o endereço de memória da variável do curso que foi encontrado anteriormente, e que obviamente será atualizado.
O código ficará desta forma:
db.Model(&curso).Update("Nome", "Go: Fundamentos de uma aplicação web com GORM")
Optei apenas por atualizar o nome do curso. Caso queira, fique à vontade para atualizar o valor das outras propriedades.
Excluindo um curso do banco de dados
Para excluir um curso, a função Delete do GORM será utilizada. Como parâmetros desta função, passaremos o endereço de memória da nossa struct de cursos, e o ID do curso que será excluído. O endereço de memória da struct servirá para o GORM identificar de qual tabela ele deverá excluir um registro. O código de exclusão de um curso ficará assim:
db.Delete(&product, 1)
Pronto, CRUD finalizado.
ORM VS SQL
Ao invés de escrever códigos SQL, podemos pedir de uma forma elegante para o GORM realizar essas ações por nós. Você pode preferir um dos dois, mas vou fazer algumas comparações.
Comparação da criação de um curso
Com SQL:
insert into cursos(nome, area, professor) values (‘Go: Fundamentos de uma aplicação web’,’Programacao’, ‘Guilherme Lima’);
Com o GORM:
db.Create(&Curso{Nome: "Go: Fundamentos de uma aplicação web", Area: "Programacao", Professor: "Guilherme Lima"})
Comparação da leitura de um curso do banco de dados
Com SQL:
select nome, area, professor, from cursos where id = 1;
Com o GORM:
var curso Curso
db.First(&curso, 1)
O GORM visivelmente nos traz facilidades e nos poupa de escrever SQL na mão, uma tarefa que boa parcela das pessoas que desenvolvem não gostam. Apesar do GORM e dos ORM´s trazerem tantos benefícios, nem tudo são flores, pois eles não são muito recomendados para realizar consultas complexas ao banco de dados. Neste caso, é recomendável criar consultas utilizando SQL puro.
Conclusão
Nesse artigo, conhecemos o conceito de ORM e vimos como eles podem nos ajudar no desenvolvimento de software mais ágil, facilitando e agilizando processos corriqueiros do desenvolvimento de software. Além disso, conhecemos um pouco da linguagem Go e do seu ORM GORM, um dos mais utilizados no mercado.
Com o GORM aprendemos a realizar o CRUD, que é a base da maioria dos sistemas existentes na internet, e vimos como ele nos auxilia bastante nessas construções.
E aí, o que você achou? Não deixe de conferir nossos cursos de Go e continue mergulhando em tecnologia!