2012-08-30 27 views
23

Necesito hacer un método de búsqueda que use la API de criterios JPA con múltiples parámetros. Ahora el problema es que no se requieren todos los parámetros. Entonces, algunos podrían ser nulos y no deberían incluirse en la consulta. Lo he intentado con el CriteriaBuilder pero no pude ver cómo hacerlo funcionar.API de criterios JPA con múltiples parámetros

Con la API de criterios de Hibernate esto es bastante fácil. Simplemente crea los criterios y luego agrega Restricciones.

Criteria criteria = session.createCriteria(someClass.class); 
if(someClass.getName() != null) { 
    criteria.add(Restrictions.like("name", someClass.getName()); 
} 

¿Cómo podría lograr lo mismo con la API de criterios de JPA?

Respuesta

59

concepto es construir gama de javax.persistence.Predicate que contiene sólo los predicados que queremos utilizar:

Ejemplo entidad a consultar:

@Entity 
public class A { 
    @Id private Long id;  
    String someAttribute; 
    String someOtherAttribute; 
    ... 
} 

propia consulta:

//some parameters to your method 
    String param1 = "1"; 
    String paramNull = null; 

    CriteriaBuilder qb = em.getCriteriaBuilder(); 
    CriteriaQuery cq = qb.createQuery(); 
    Root<A> customer = cq.from(A.class); 

    //Constructing list of parameters 
    List<Predicate> predicates = new ArrayList<Predicate>(); 

    //Adding predicates in case of parameter not being null 
    if (param1 != null) { 
     predicates.add(
       qb.equal(customer.get("someAttribute"), param1)); 
    } 
    if (paramNull != null) { 
     predicates.add(
       qb.equal(customer.get("someOtherAttribute"), paramNull)); 
    } 
    //query itself 
    cq.select(customer) 
      .where(predicates.toArray(new Predicate[]{})); 
    //execute query and do something with result 
    em.createQuery(cq).getResultList(); 
+1

¿Cómo se obtiene la instancia 'em'? – Alex

+1

@Alex em, que es EntityManager, probablemente solo se conectará automáticamente. Tu clase de configuración lo configuraría. –

3

Echa un vistazo a este sitio JPA Criteria JPA. Hay muchos ejemplos.

Actualización: Proporcionar un ejemplo concreto

búsqueda Vamos a cuentas con un saldo inferior a un valor específico:

SELECT a FROM Account a WHERE a.balance < :value 

En primer lugar crear un Constructor Criterios

CriteriaBuilder builder = entityManager.getCriteriaBuilder(); 

CriteriaQuery<Account> accountQuery = builder.createQuery(Account.class); 
Root<Account> accountRoot = accountQuery.from(Account.class); 
ParameterExpression<Double> value = builder.parameter(Double.class); 
accountQuery.select(accountRoot).where(builder.lt(accountRoot.get("balance"), value)); 

Para llegar el resultado establece el (los) parámetro (s) y ejecuta la consulta:

TypedQuery<Account> query = entityManager.createQuery(accountQuery); 
query.setParameter(value, 1234.5); 
List<Account> results = query.getResultList(); 

BTW: El entityManager se inyecta en algún lugar de un EJB/Service/DAO.

+0

Si no configuro un parámetro, ¿cómo se reflejará esto en la consulta? Como todavía necesito agregar los otros parámetros a CriteriaQuery. Y si uno de ellos es nulo, esto generará resultados inesperados. – mokuril

0

respuesta de Mikko trabajó hermosamente. El único cambio que tuve que hacer fue: En lugar de: cq.select (cliente) .where (predicates.toArray (nuevo Predicate [] {})); REEMPLAZO CON: predicado [] predicatesarr = predicates.toArray (nuevo predicado [predicates.size()]); cq.select (cliente) .where (predicatesarr);

En algún lugar no funcionó la conversión de lista a matriz en el original.

Cuestiones relacionadas