Search using Criteria with WHERE, AND and OR

Asked

Viewed 604 times

1

I’m trying to do a survey using Criteria, the research would be this:

SELECT *
FROM lefacil.pap_produto a
WHERE (a.marca='Fabber Castell' or a.marca='Tilibra') AND (a.quantidadeCores='12 Cores' or a.quantidadeCores='24 Cores');

I have already researched and made several tests, but I could not get the result of the above search. Follow the class I’m using to do the tests

public class TesteBancoCriteriaPredicateComArray {

public static void main(String[] args) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("LefacilPU");
EntityManager manager = factory.createEntityManager();

EntityTransaction trx = manager.getTransaction();
trx.begin();

CriteriaBuilder cb = manager.getCriteriaBuilder();

CriteriaQuery<ProdutoPap> cq = cb.createQuery(ProdutoPap.class);
Root<ProdutoPap> root = cq.from(ProdutoPap.class);

// parametros
ArrayList<String> param1 = new ArrayList<>();
//aqui coloquei somente um objeto para teste, mas preciso que seja um Array
param1.add("Fabber Castell");
ArrayList<String> param2 = new ArrayList<>();
param2.add("24 Cores");
param2.add("12 Cores");

List<Predicate> predicates = new ArrayList<Predicate>();

if (param1 != null) {
 predicates.add(cb.equal(root.get("marca"), param1));
}

if (param2 != null) {
    Iterator<String> a = param2.iterator();
    while (a.hasNext()) {
        predicates.add(cb.equal(root.get("quantidadeCores"), a.next()));
 }
}
cq.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));

System.out.println(manager.createQuery(cq).getResultList());

trx.commit();
}
}

What I want is a correct way to do the above research using Criteria.

  • Any specific reason for wanting the consultation on Criteria?

  • I’m setting up a system, and in these researches where I need to search for several parameters I think it’s much better to make use of Criteria.

1 answer

1


Criteria

In that case, it is simpler to use the clause IN than the clause OR. So, your Criteria would look that way:

// parametros
Set<String> marcas = new HashSet<>();
marcas.add("Fabber Castell");
Set<String> quantidadeCores = new HashSet<>();
quantidadeCores.add("12 Cores");
quantidadeCores.add("24 Cores");

EntityManagerFactory emf = Persistence.createEntityManagerFactory("LefacilPU");
EntityManager em = emf.createEntityManager();

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<ProdutoPap> cq = cb.createQuery(ProdutoPap.class);
Root<ProdutoPap> root = cq.from(ProdutoPap.class);

Predicate marcaIgual = root.get("marca").in(marcas);
Predicate quantidadeIgual = root.get("quantidadeCores").in(quantidadeCores);

cq.where(cb.and(marcaIgual, quantidadeIgual));
em.createQuery(cq)
    .getResultList()
    .forEach(System.out::println);

em.close();
emf.close();

JPQL

A simpler option is the use of JPQL. The consultation would look like this:

// parametros
Set<String> marcas = new HashSet<>();
marcas.add("Fabber Castell");
Set<String> quantidadeCores = new HashSet<>();
quantidadeCores.add("12 Cores");
quantidadeCores.add("24 Cores");

EntityManagerFactory emf = Persistence.createEntityManagerFactory("LefacilPU");
EntityManager em = emf.createEntityManager();

//Obs: como não sei se como está organizada a sua classe LeFacil coloquei desta forma
//adapte a resposta caso não corresponda ao seu modelo
String query = "SELECT l FROM LeFacil l WHERE l.pap_produto.marca IN :marcas "
            + "AND l.pap_produto.quantidadeCores IN :quantidadeCores";

em.createQuery(query, LeFacil.class)
    .setParameter("marcas", marcas)
    .setParameter("quantidadeCores", quantidadeCores)
    .getResultList()
    .forEach(System.out::println);

em.close();
emf.close();
  • Thank you very much Felipe, helped me a lot!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.