Combinando Predicados de JPA e/ou Critérios

Combinando Predicados de JPA e / ou Critérios

1. Visão geral

A API de critérios JPA pode ser usada para adicionar facilmente várias condições de E / OU ao consultar registros em um banco de dados. Neste tutorial, vamos explorar um exemplo rápido de consultas de critérios JPA que combinam vários predicados AND / OR.

Se você não está familiarizado com predicados, sugerimos ler sobrebasic JPA criteria queries primeiro.

2. Aplicação de amostra

Para nossos exemplos, vamos considerar um inventário de entidadesItem, cada uma tendo umid,name,color egrade:

@Entity
public class Item {

    @Id
    private Long id;
    private String color;
    private String grade;
    private String name;

    // standard getters and setters
}

3. Combinando dois predicados OR usando um predicado AND

Vamos considerar o caso de uso em que precisamos encontrar itens com ambos:

  1. cor vermelha ou azul E

  2. Grau A ou B

Podemos fazer isso facilmenteusing JPA Criteria API’s and() and or() compound predicates.

Para começar, vamos configurar nossa consulta:

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Item.class);
Root itemRoot = criteriaQuery.from(Item.class);

Agora, precisaremos construir umPredicate para encontrar itens de cor azul ou vermelha:

Predicate predicateForBlueColor
  = criteriaBuilder.equal(itemRoot.get("color"), "blue");
Predicate predicateForRedColor
  = criteriaBuilder.equal(itemRoot.get("color"), "red");
Predicate predicateForColor
  = criteriaBuilder.or(predicateForBlueColor, predicateForRedColor);

A seguir, vamos construir umPredicate para encontrar itens de grau A ou B:

Predicate predicateForGradeA
  = criteriaBuilder.equal(itemRoot.get("grade"), "A");
Predicate predicateForGradeB
  = criteriaBuilder.equal(itemRoot.get("grade"), "B");
Predicate predicateForGrade
  = criteriaBuilder.or(predicateForGradeA, predicateForGradeB);

Por fim, definimos o ANDPredicate desses dois, aplicamos o métodowhere() e executamos nossa consulta:

Predicate finalPredicate
  = criteriaBuilder.and(predicateForColor, predicateForGrade);
criteriaQuery.where(finalPredicate);
List items = entityManager.createQuery(criteriaQuery).getResultList();

4. Combinando dois predicados AND usando um predicado OR

Por outro lado, vamos considerar o caso em que precisamos encontrar itens com:

  1. cor vermelha e grau D OU

  2. cor azul e grau B

A lógica é bastante semelhante, mas aqui criamos dois ANDPredicates primeiro e depois os combinamos usando um ORPredicate:

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Item.class);
Root itemRoot = criteriaQuery.from(Item.class);

Predicate predicateForBlueColor
  = criteriaBuilder.equal(itemRoot.get("color"), "red");
Predicate predicateForGradeA
  = criteriaBuilder.equal(itemRoot.get("grade"), "D");
Predicate predicateForBlueColorAndGradeA
  = criteriaBuilder.and(predicateForBlueColor, predicateForGradeA);

Predicate predicateForRedColor
  = criteriaBuilder.equal(itemRoot.get("color"), "blue");
Predicate predicateForGradeB
  = criteriaBuilder.equal(itemRoot.get("grade"), "B");
Predicate predicateForRedColorAndGradeB
  = criteriaBuilder.and(predicateForRedColor, predicateForGradeB);

Predicate finalPredicate
  = criteriaBuilder
  .or(predicateForBlueColorAndGradeA, predicateForRedColorAndGradeB);
criteriaQuery.where(finalPredicate);
List items = entityManager.createQuery(criteriaQuery).getResultList();

5. Conclusão

Neste tutorial, usamos a API JPA Criteria para implementar casos de uso em que precisamos combinar predicados AND / OR.

Como de costume, o código-fonte completo usado para este tutorial éover on GitHub.