2012-08-30 53 views
23

我需要製作一個使用帶有多個參數的JPA Criteria API的搜索方法。 現在的問題是,並非每個參數都是必需的。所以有些可能是空的,它們不應該包含在查詢中。我已經用CriteriaBuilder試過了,但是我看不到如何使它工作。具有多個參數的JPA Criteria API

使用Hibernate Criteria API這非常簡單。只需創建條件,然後添加限制。

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

我該如何實現與JPA的Criteria API相同?

回答

59

觀是構建的javax.persistence.Predicate陣列只包含謂詞,我們要使用:

例實體進行查詢:

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

查詢本身:

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

你如何得到'em'實例? – Alex

+1

@Alex em,即EntityManager,可能只是自動裝入。你的配置類會設置它。 –

3

看看這個網站JPA Criteria JPA。有很多例子。

更新:提供一個具體的例子

讓我們搜索帳戶具有比規定的值時的平衡:

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

首先創建一個標準生成器

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

要獲得結果設置參數並運行查詢:

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

BTW:entityManager被注入EJB/Service/DAO的某個地方。

+0

如果我沒有設置參數,這將如何反映在查詢中?因爲我仍然需要將其他參數追加到CriteriaQuery。如果其中一個爲空,則會導致意想不到的結果。 – mokuril

0

米克的答案工作精美。只有我需要做的變化是: 而不是: cq.select(customer) .where(predicates.toArray(new Predicate [] {})); 替換爲: 謂詞[] predicatesarr = predicates.toArray(new Predicate [predicates.size()]); cq.select(customer).where(predicatesarr);

從原始列表轉換到數組的某處不起作用。