2012-08-30 15 views
23

Devo eseguire un metodo di ricerca che utilizza l'API Criteri JPA con più parametri. Ora il problema è che non tutti i parametri sono obbligatori. Quindi alcuni potrebbero essere nulli e non dovrebbero essere inclusi nella query. Ho provato questo con il CriteriaBuilder ma non ho potuto vedere come farlo funzionare.API JPA Criteria con più parametri

Con l'API Hibernate Criteria questo è abbastanza facile. Basta creare i criteri e quindi aggiungere restrizioni.

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

Come è possibile ottenere lo stesso risultato con l'API Criteri di JPA?

risposta

59

concetto è quello di costruire array di javax.persistence.Predicate che contiene solo predicati che vogliamo usare:

entità Esempio da interrogare:

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

query stessa:

//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

Come si ottiene l'istanza di 'em'? – Alex

+1

@Alex em, che è EntityManager, verrebbe probabilmente avviato automaticamente. La tua classe di configurazione lo imposterà. –

3

Date un'occhiata a questo sito JPA Criteria JPA. Ci sono molti esempi

Aggiornamento: Fornire un esempio concreto

di ricerca di Let per gli account con un saldo inferiore a un valore specifico:

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

Innanzitutto creare un cantiere Criteri

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)); 

Per ottenere il risultato imposta i parametri ed esegue la query:

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

BTW: L'entityManager viene iniettato da qualche parte in un EJB/Service/DAO.

+0

Se non si imposta un parametro, come si rifletterà nella query? Poiché ho ancora bisogno di aggiungere gli altri parametri a CriteriaQuery. E se uno di questi è nulla, ciò porterà a risultati inaspettati. – mokuril

0

risposta di Mikko ha funzionato splendidamente. Solo il cambiamento che dovevo fare era: Invece di: cq.select (cliente) . Where (predicates.toArray (new Predicate [] {})); SOSTITUITO CON: Predicato [] predicatesarr = predicates.toArray (new Predicate [predicates.size()]); cq.select (cliente) .where (predicatesarr);

Da qualche parte la conversione da elenco a matrice nell'originale non ha funzionato.

Problemi correlati