Quem é melhor? ORM ou SQL puro?
Tags: orm, sql, programming, productivity
Published: 2023-04-21 21:12:41

Olá! Hoje vamos ver um pouco sobre o dilema de usar ORM ou SQL puro nos seus projetos. Nesse post vou abordar os seguintes pontos:

{% details Sumário %} 
- 1. Introdução
  - 1.1 SQL Puro?
  - 1.2 O que é ORM?
- 2. Performance
  - 2.1 O famoso N+1
- 3. Produtividade
- 4. Escalabilidade
- 5. Conclusão
{% enddetails %}

Espero que você goste e que principalmente te ajude no dia a dia, no mais é isso e boa leitura :)

> OBS: Não se esqueça de fornecer seu feedback, isso me ajuda demais em criar novos conteúdos.

=================================================

## 1. Introdução

Se você já aprendeu a construir uma aplicação, nem que seja simples, provavelmente já ouviu falar de banco de dados. Por mais que você possa não saber o que é isso, eu vou te explicar de maneira superficial (coloca nos comentários se você quer um post especialmente sobre banco de dados).

> "Banco de dados é um local é onde se guarda os dados de uma aplicação".
> 
> _Lucas Jdev_

Alguns bancos de dados são SQL (_Structure Query Language_) outros NoSql, mas vamos focar aqui nesse post em SQL, ok? 

Ok, sabendo disso, há situações no dia a dia de desenvolvimento que pode causar um impasse em algumas pessoas, como por exemplo: "Desenvolver o banco e efetuar operações com SQL puro ou usar ORM?".

Caso você não saiba o que é ORM ou o que é SQL puro? fica frio e segue o fio.

### 1.1 SQL puro

Caso você não saiba o que é isso, basicamente é a linguagem de estilo funcional para bancos de dados relacionais, ou seja, com ela você informa para o banco o que fazer e não como fazer. Com ela conseguimos salvar os dados no banco, atualizar, deletar e efetuar até mesmo busca específicas sobre os dados.

SQL é extremamente importante para a vida de desenvolvedor, ora, se você nunca sofreu um pouquinho criando conexões e lidando com transações jdbc da vida, você ainda não viveu o suficiente kkkk, mas brincadeiras a parte, é muito interessante saber como utilizar ela pois ela é a base para entender ORM.

"O que raios é esse negócio de ORM que você tanto fala?", calma, segue o fio.

### 1.2 O que é ORM?

ORM é uma sigla para Object-Relational Mapping, ou seja, Mapeamento Objeto Relacional. ORM por si só é uma técnica de permite que as aplicações trabalhem com objetos em vez de lidar com tabelas sql por cima dos panos. Entretanto, geralmente quando falamos de ORM, estamos nos referindo a ferramentas de desenvolvimento, os famosos frameworks ORM.

Existem diversos frameworks ORM no mercado como o famoso Prisma, Elouquent, Hibernate etc. Ele é muito útil no dia a dia, pois possibilita padronizar e automatizar tarefas rotineiramente repetitivas no cotidiano de dev.

Agora que você já sabe superficialmente o que são ambos, tenha fixado na cabeça uma coisa "Nem tudo são flores". Usar SQL puro tem suas vantagens, muito boas por sinal, mas também não é um mar de rosas. A mesma ideia serve para ORM, pois há muitas vantagens como produtividade de desenvolvimento, entretanto, há algumas desvantagens no seu uso a depender do caso.

"Mas o que são essas vantagens e desvantagens na real? Dá pra fazer algum comparativo entre ambos?", neste post eu pretendo trazer 3 pontos que eu julguei interessantes para ser debatidos (caso discorde, comenta aí) são eles: Performance, produtividade e escalabilidade.

## 2. Performance

Sim, comecei por uma das partes mais polêmicas quando se trata de ORM. "Mas por quê?" Algumas pessoas afirmam que ORM é muito menos performático do que usar SQL puro. De fato, não há como negar que ter uma camada de abstração em uma infraestrutura como a camada de dados aumenta a latência, isso é inquestionável. Porém, entretanto e todavia, essa diferença de latência pode ser desprezível a depender do nível da tua aplicação.

"Calma, que raios de camada é essa que você falou?", segue o fio das imagens:

![ilustracao-comunicacao-sql-puro](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fddw1ei93uiw4hwhoxtn.png)

Na imagem acima você consegue ver como é o processo com SQL puro na sua aplicação. Resumindo, você terá um driver de conexão que permite a conexão direta com o banco de dados.


![ilustracao-comunicacao-com-orm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xie31aqwjfqrjevjja1v.png)

Já nesta imagem você consegue ver claramente que há uma camada a mais, camada essa que pode gerar um overhead adicional na aplicação, nossa camada de ORM, uma abstração a mais.

"Mas pera... em um caso hipotético que eu tenho uma aplicação de CRUD para uma padaria da minha vizinhança, qual é melhor? julgando unicamente Performance?", já que você está com teimosia, vamos julgar somente nesse critério. Bom... a resposta é que não faz diferença nesse caso kkkk. A latência só influencia mais em aplicações mais robustas que precisam mais do que um CRUD simples ou consultas simples.

"Ah Lucas, mas meu papel como desenvolvedor não é fazer o melhor software possível?", lembre-se que decisões não são tomadas levando somente um fator em consideração, deve ser levado em consideração a produtividade da equipe (ou euquipe), tempo de entrega, requisitos do sistema etc. Criar software não é só pegar umas tecnologias aleatórias e implementar, vai muito além do que isso.

### 2.1 O famoso N+1

"Ei, eu vi uma coisa uma vez sobre o problema N+1 que os ORM's têm!", bem lembrado, esses frameworks de persistência geralmente possui um "problema" de consultar mais do que devem, não entendeu? então se liga nesse caso:

> Você criou um CRUD relacional simples com o hibernate em que um cliente possui vários pedidos.

código das classes:
```Java
@Entity
public class Cliente {
    @Id
    private Long id;
    private String nome;
  
    @OneToMany
    private List<Pedido> pedidos;
    // getters e setters
}

@Entity
public class Pedido {
    @Id
    private Long id;
    private BigDecimal valor;

    @ManyToOne 
    private Cliente cliente
    // getters e setters
}
```

Depois de ter criado as classes que serão as representações de tabelas no banco, vamos para o cenário em que você chama um findAll para clientes, ou seja, você busca uma lista de todos os clientes que estão contidos no banco de dados.

as queries geradas pelo ORM seriam:
```sql
SELECT * FROM CLIENTE;

SELECT * FROM PEDIDO WHERE ID_CLIENTE = 1;
SELECT * FROM PEDIDO WHERE ID_CLIENTE = 2;
SELECT * FROM PEDIDO WHERE ID_CLIENTE = 3;
SELECT * FROM PEDIDO WHERE ID_CLIENTE = 4;
...
```

O ORM entende que primeiro deve fazer a query `SELECT * FROM CLIENTE`, mas daí, depois que ele fez, ele percebe que precisa agora dos pedidos do cliente, ou seja, para cada uma consulta de buscar todos os clientes, ele tem que ir mais N vezes no banco para pegar os dados agregados.

"Por quê o ORM trabalha desse jeito? tá só gerando query indesejada, seria muito mais vantajoso fazer um INNER JOIN com SQL puro", de fato tá criando queries indesejadas, deixando o sistema mais suscetível a gargalos futuros, mas há solução para isso, geralmente é simples a correção disso. A curva de aprendizado para sacar que esse problema existe e solucionar não é grande, principalmente se a pessoa souber manipular SQL.

ORM's geralmente possuem uma flexibilidade muito boa para solucionar esse tipo de problema, como por exemplo, escrevendo uma query na linguagem do framework ou escrevendo SQL puro dentro do ORM.

## 3. Produtividade

Nem só de performance vive o homem (na minha cabeça isso teve graça, mas enfim). Produtividade é um fator muito relevante quando se trata de tomada de decisão, sem ele, não conseguimos ter uma boa dimensão do que vale a pena ou não.

SQL pode ser muito produtivo em termos de escrita de queries quando há uma equipe que sabe muito bem o que está fazendo. No entanto, em termos de manutenção, pode ser um desafio, especialmente quando há uma leve alteração na estrutura do banco de dados ou uma migração para um SGBD (Sistema Gerenciador de Banco de dados) diferente. Desenvolvedores podem usar recursos específicos de um determinado SGBD, como PostgreSQL, Oracle ou MySQL, para alcançar um desempenho melhor, mas isso pode se tornar uma dor de cabeça na hora de migrar para outro SGBD. Além disso, uma mudança em uma coluna no banco de dados pode exigir alterações em várias queries para se adequar à mudança.

"Mas e o ORM?" - Bem, há uma vantagem muito grande em termos de produtividade que os ORM's trazem para nós, principalmente os mais conhecidos. Os ORM's permitem uma facilidade em termos de padronização de queries SQL, permitindo a troca de SGBD (os quais eles têm suporte) sem muitas dores de cabeça. Muitos ORM's conseguem gerar o SQL das tabelas e colocá-lo em um arquivo `.sql` para ajudar em futuras migrações, alguns geram até mesmo o famoso DER (Diagrama Entidade-Relacionamento), como é o caso do Prisma.

Venhamos e convenhamos, é extremamente produtivo conseguir fazer isso rapidamente com poucas configurações durante o desenvolvimento do código.

Usando SQL puro, você provavelmente teria que ter um workbench para gerar os relacionamentos do modelo lógico, e seria necessário um pouco de trabalho para obter esse diagrama.

Além disso, muitos frameworks ORM já fornecem queries prontas para consumo no desenvolvimento, como métodos como findAll, findById, create e delete, o que diminui o custo de manutenção de uma maneira surreal, dependendo do caso.

De longe, o ORM é maravilhoso para criar um MVP.

Então acho que até agora está 1 x 1.

## 3. Escalabilidade

Primeiro de tudo, o que é Escalabilidade? Ao meu ver, é a capacidade do software de continuar funcionando de forma eficiente mesmo quando a quantidade de usuários, transações ou dados aumenta significativamente.

Ok, agora vamos definir uma coisa: tanto ORM quanto SQL puro podem ser escaláveis, desde que utilizados corretamente e com a configuração adequada do banco de dados e do ambiente de execução.

No caso do ORM, ele pode facilitar a implementação de boas práticas de otimização e escalabilidade, como a criação de índices, o uso de cache de segundo nível, o lazy loading e a escrita de consultas otimizadas.

Dependendo do tipo de projeto que você está trabalhando, usar um ORM pode não ser a melhor opção se o modelo de dados for muito complexo. Isso porque, quanto mais complexo o modelo, mais difícil pode ser escrever consultas otimizadas usando o ORM. Além disso, se você estiver lidando com muitos usuários ou muitos dados ao mesmo tempo, pode ser necessário ter um controle mais detalhado do acesso ao banco de dados. Isso pode ser difícil de fazer usando um ORM, então pode ser melhor usar SQL puro ou até mesmo procedimentos armazenados no banco de dados para garantir que tudo funcione bem e que você possa controlar quem acessa o que.

Entretanto, pode ser também mais difícil manter uma aplicação com SQL puro, pois quanto mais controle você tem sobre as consultas, mais cuidado precisa ter em pontos de manutenção.

Particularmente falando, eu considero um empate, apesar dos benefícios e desvantagens do ORM, o uso de SQL puro também pode trazer uma grande dor de cabeça, dependendo da equipe que está trabalhando no projeto.

## 4. Conclusão

Nesta postagem, foram discutidas algumas vantagens e desvantagens do uso de ORM e SQL puro. Embora muitos esperassem um vencedor claro na disputa, a verdade é que a escolha entre as tecnologias depende do contexto de cada projeto.

Se você está acostumado com o uso de SQL puro, pode ser interessante experimentar o uso de ORM na sua linguagem de programação. Não se limite a uma única tecnologia, pois quanto mais você souber extrair o melhor de diferentes ferramentas, maior será sua capacidade de adaptação a diferentes stacks.

Se me perguntarem qual tecnologia eu escolheria para criar uma aplicação agora, minha resposta seria ORM, pois já estou familiarizado com o processo de tradução do ORM para SQL, o que me permite ser mais produtivo. No entanto, se eu perceber que o projeto exige maior desempenho ou refinamento, provavelmente começaria com SQL puro. Mas, é importante lembrar que essa é apenas uma opinião pessoal e que a escolha entre as tecnologias deve ser feita com base no contexto e nas necessidades específicas de cada projeto.

> "Texto sem contexto, vira pretexto!"
>
> _Elemar Júnior_

---

**Referências**
- Youtube:
 - Código Fonte TV: ORM (A Ponte entre Orientação a Objetos e o Banco de Dados);
 - Rodrigo Branas: SQL ou ORM: E Agora? (Não tenha medo de SQL);
 - Balta.io: ORM vs SQL puro; 
 - DevSuperior: Problema N+1 Consultas;
- Artigos:
 - [Why ORMs are slow (and getting slower)](https://www.edgedb.com/blog/why-orms-are-slow-and-getting-slower);
 - [How to solve the N+1 problem in Spring Data JPA? - Stack Overflow](https://stackoverflow.com/questions/61637545/how-to-solve-the-n1-problem-in-spring-data-jpa);
 - [Should you use Raw SQL or an ORM?](https://medium.com/codex/should-you-use-raw-sql-or-an-orm-18468c11c1a9);
 - [ORM's x Query Builder's x Raw SQL](https://dev.to/pedrocardoz0/orm-s-x-query-builder-s-x-raw-sql-2oal).