Search using Criteria with WHERE, AND and OR

1

I'm trying to do a search using Criteria , the search 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 already researched and ran several tests, but I was not able to get the search result listed above. Here's 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 search using Criteria .

    
asked by anonymous 01.12.2017 / 19:30

1 answer

1

Criteria

In this case, it is simpler to use the IN clause than the OR clause. So your Criteria 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();

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 to use JPQL . The query 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();
    
01.12.2017 / 21:06