Introdução
Introdução
JPA Consultas - Introdução
No contexto de persistência de dados em Java, o JPA (Java Persistence API) oferece diversas maneiras de consultar o banco de dados de forma eficiente e estruturada. Dependendo dos requisitos da aplicação, é possível escolher entre diferentes abordagens de consulta, como consultas nativas, JPQL (Java Persistence Query Language) e JPA Repository.
Cada uma dessas formas de consulta tem suas características, vantagens e situações ideais de uso. Vamos explorar cada uma delas em detalhes:
Contexto
Aqui está uma estrutura simples de uma entidade Cliente utilizando JPA, contendo os atributos id, nome, aniversario, renda e cidade para podermos praticar as diferentes abordagens para a realização de consulta de dados com JPA.
import jakarta.persistence.*;
import lombok.Data;
import java.time.LocalDate;
@Entity
@Table(name = "tab_cliente")
@Data
public class Cliente {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_cliente")
    private Integer id;
    @Column(name = "nome_completo")
    private String nome;
    @Column(name = "dt_aniversario")
    private LocalDate aniversario;
    @Column(name = "renda_media")
    private Double renda;
    @Column(name = "nome_cidade")
    private String cidade;
    @Override
    public String toString() {
        return "Cliente{" +
                "id=" + id +
                ", nome='" + nome + '\'' +
                ", aniversario=" + aniversario +
                ", renda=" + renda +
                ", cidade='" + cidade + '\'' +
                '}';
    }
}
Cliente em relação a tabela no banco de dados para facilitar a compreensão entre SQL e JPQL.Nativas
As consultas nativas no JPA são aquelas que utilizam a linguagem SQL tradicional para interagir diretamente com o banco de dados. Diferentemente das consultas JPQL, que são baseadas na estrutura das entidades, as consultas nativas trabalham diretamente com as tabelas e colunas do banco.
Particularidades:
- SQL Puro: Permite o uso de SQL direto, o que significa que você pode escrever consultas específicas do banco de dados, com total controle sobre a sintaxe e a execução.
 - Desempenho: Por ser uma consulta direta ao banco, pode ser mais eficiente em alguns casos, especialmente quando você precisa de otimizações específicas.
 - Portabilidade: Ao usar SQL nativo, a portabilidade entre diferentes bancos de dados pode ser comprometida, pois a consulta pode depender de recursos ou sintaxe específicos do banco.
 - Exemplo de uso:
 
Query query = entityManager.createNativeQuery("SELECT * FROM tab_cliente WHERE nome_completo = ?", Cliente.class);
query.setParameter(1, "João");
List<Cliente> clientes = query.getResultList();
Nome dos parâmetros:
Você também pode definir um nome aos parâmetros em suas consultas utilizando a padrão :nomeParametro
Query query = entityManager.createNativeQuery("SELECT * FROM tab_cliente WHERE nome_completo = :nome", Cliente.class);
query.setParameter("nome", "João");
List<Cliente> clientes = query.getResultList();
JPQL
O JPQL é uma linguagem de consultas específica do JPA, baseada na estrutura das entidades, e não nas tabelas do banco. Com o JPQL, você pode criar consultas que operam sobre os objetos Java e suas relações, em vez de trabalhar diretamente com o banco de dados.
Particularidades:
- Orientado a Objetos: JPQL é uma linguagem orientada a objetos, ou seja, você consulta as entidades Java (não as tabelas do banco), o que torna as consultas mais flexíveis e alinhadas com o modelo de objetos.
 - Portabilidade: Uma das principais vantagens do JPQL é a portabilidade, pois o JPA converte as consultas para SQL específico do banco em tempo de execução. Isso permite que você escreva consultas independentes do banco de dados, facilitando a troca de banco sem reescrever as consultas.
 - Menos Flexibilidade que SQL Nativo: Embora o JPQL seja muito poderoso, ele não tem a mesma flexibilidade do SQL nativo, especialmente quando se trata de recursos específicos do banco (como funções específicas do banco).
 - Exemplo de uso:
 
TypedQuery<Cliente> query = entityManager.createQuery("SELECT c FROM Cliente c WHERE c.nome = :nome", Cliente.class);
query.setParameter("nome", "João");
List<Cliente> clientes = query.getResultList();
JPA Repository
O JPA Repository faz parte do Spring Data JPA e fornece uma abstração de alto nível para a manipulação de dados, simplificando a criação e execução de consultas. Ele é baseado no uso de interfaces e permite que você crie consultas de forma declarativa ou personalizada, sem precisar escrever código SQL ou JPQL manualmente.
Particularidades:
- Facilidade e Abstração: O JPA Repository fornece métodos prontos para operações básicas como 
save,findAll,findById, entre outros, sem precisar de implementação adicional. Isso economiza tempo e evita a repetição de código. - Consultas Customizadas: Para consultas mais complexas, é possível definir métodos personalizados na interface de repositório utilizando JPQL ou até mesmo consultas nativas.
 - Exemplo de uso:
 
public interface ClienteRepository extends JpaRepository<Cliente, Long> {
    List<Cliente> findByNome(String nome);
}
Nesse exemplo, o método findByNome é gerado automaticamente pelo Spring Data JPA, sem precisar de uma implementação explícita. Você também pode criar consultas personalizadas usando a anotação @Query.
Exemplo de consulta customizada com @Query:
public interface ClienteRepository extends JpaRepository<Cliente, Long> {
    @Query("SELECT c FROM Cliente c WHERE c.nome = :nome")
    List<Cliente> buscarPorNome(@Param("nome") String nome);
}
O uso de JPA Repository é altamente recomendado quando você quer simplificar a interação com o banco de dados e evitar a escrita manual de código de consulta, mas ainda precisa de flexibilidade para personalizar consultas complexas.
Conclusão
No JPA, as diferentes abordagens de consulta — nativas, JPQL e JPA Repository — oferecem soluções adequadas para diversos cenários:
- Consultas Nativas são ideais quando você precisa de controle total sobre a consulta SQL ou quando requer funcionalidades específicas do banco de dados.
 - JPQL é a escolha recomendada quando você deseja escrever consultas independentes do banco de dados, alinhadas com o modelo de objetos da aplicação, garantindo portabilidade e flexibilidade.
 - JPA Repository oferece uma abstração poderosa, simplificando a criação de consultas e operações CRUD básicas, além de permitir a criação de consultas customizadas com o uso de JPQL ou SQL nativo.
 
A escolha entre essas abordagens depende das necessidades do seu projeto, do nível de controle sobre as consultas que você deseja e do equilíbrio entre simplicidade e flexibilidade.