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.
GO TO FULL VERSION