Introdução à API de critérios

Existem duas maneiras de escrever consultas de banco de dados no Hibernate:

  • Hibernate Query Language
  • API de critérios

Você já conhece o primeiro há muito tempo, é hora de se familiarizar com a Criteria API. Esta é uma ferramenta muito poderosa, em algum momento foi ainda mais popular que o HQL. Agora não é mais tão popular, mas para algumas tarefas será definitivamente uma solução melhor do que HQL.

Em qualquer caso, você não pode aprender Hibernate sem se familiarizar com a Criteria API. Vamos escrever um pequeno exemplo e depois vamos analisá-lo. Por exemplo, vamos solicitar todos os funcionários (Funcionário) do banco de dados. Aqui está o que obteremos:

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Employee> critQuery = builder.createQuery(Employee.class);

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Query<Employee> query = session.createQuery(critQuery);
List<Employee> results = query.getResultList();

Parece complicado. Vamos escrever a mesma consulta HQL para comparação:

String hqlQuery = "from Employee";

Query<Employee> query = session.createQuery(hqlQuery);
List<Employee> results = query.getResultList();

Observe que as duas últimas linhas de ambos os exemplos são quase idênticas: criamos um objeto Query e o usamos para obter uma List. Isso indica que o restante das linhas está fazendo algo idêntico.

Observe as linhas 3 e 4 do primeiro exemplo:

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Vamos escrevê-los em uma linha:

critQuery.select(critQuery.from(Employee.class));

Não te lembra nada? E se você colorir um pouco diferente:

critQuery.select(critQuery.from(Employee.class));

Sim, esta é uma construção complicada da consulta SELECT FROM.

Exemplos de como trabalhar com a Criteria API

Para um melhor entendimento, darei apenas alguns exemplos.

Pedido 1 . Obtenha todos os funcionários com salário acima de 10 mil:

critQuery.select(critQuery.from(Employee.class)).where(builder.gt(root.get("salary"), 10000));

Pedido 2 . Obtenha todos os funcionários com salário inferior a 50 mil:

critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 50000));

Pedido 3 . Obtenha todos os funcionários cujo cargo contenha a palavra "teste":

critQuery.select(critQuery.from(Employee.class)).where(builder.like(root.get("occupation"), "%test%"));

Pedido 4 . Obtenha todos os funcionários com salário de 10 a 50 mil:

critQuery.select(critQuery.from(Employee.class)).where(builder.between(root.get("salary"), 10000, 50000));

Pedido 5 . Obtenha todos os funcionários cujo nome é nulo:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNull(root.get("name")));

Pedido 6 . Obtenha todos os funcionários cujo nome não é nulo:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNotNull(root.get("name")));

É uma maneira complicada de construir uma consulta:

  • Primeiro você pega o objetoCriteriaBuilder.
  • Em seguida, use-o para criar um objetoCriteriaQuery.
  • Então você começa a adicionar peças a ele comCriteriaQueryECriteriaBuilder.

É assim que você pode definir parâmetros para:

  • SELECIONE
  • DE
  • ONDE

Também usandoCriteriaBuildervocê pode construir diferentes condições para WHERE.

Trabalho avançado com Criteria API

Usando a Criteria API, você pode construir uma consulta de qualquer complexidade. E esta é uma ótima notícia. Por exemplo, você deseja uma cláusula WHERE complexa. Veja como fazer:

Predicate greaterThan = builder.gt(root.get("salary"), 1000);
Predicate testers = builder.like(root.get("occupation"), "test%");

critQuery.select(critQuery.from(Employee.class)).where(builder.or(greaterThan, testers));

Se você quiser escrever AND em vez de OR, basta alterar a última linha:

critQuery.select(critQuery.from(Employee.class)).where(builder.and(greaterThan, testers));

Tudo é realmente muito simples. Deixe-me dar uma tabela com algumas comparações:

SQL Método registro completo
a<b lt(a, b) construtor.lt(a, b)
a > b gt(a, b) construtor.gt(a, b)
a ou B ou (a, b) construtor.or(a, b)
a e b e(a,b) construtor.e(a,b)
um LIKE b gostar(a,b) construtor.like(a, b)
a ENTRE (c, d) entre (a, c, d) construtor.entre(a, c, d)
a É NULO isNull(a) construtor.isNull(a)
a NÃO É NULO isNotNull(a) construtor.isNotNull(a)

Tudo é simples, não é?

E como adicionamos classificação à consulta? Muito simples:

critQuery.select( critQuery.from(Employee.class) );
critQuery.where( builder.and(greaterThan, testers) );
critQuery.orderBy( builder.asc(root.get("salary"), builder.desc(root.get("joinDate") )

Você acabou de chamar o objetoCriteriaQueryorderBy () e passe os parâmetros necessários para ele.

Veja como a mesma consulta ficaria em HQL. Comparar:

select * from Employee
where (…) and (…)
order by 'salary' asc, 'joinDate' desc

Você só precisa se lembrar de 3 coisas:

  • Operadores chave como SELECT, FROM, WHERE são chamados em um objetoCriteriaQuery.
  • Operadores auxiliares como AND, OR, DESC são chamados no objetoCriteriaBuilder.
  • Os nomes dos campos são retirados do objeto via get()raiz.