2012-08-30 24 views
23

複数のパラメータでJPA Criteria APIを使用する検索方法を作成する必要があります。 問題は、すべてのパラメータが必要というわけではないということです。したがって、いくつかはnullになる可能性があり、クエリに含めないでください。私は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は、おそらくautowiredであるはずです。あなたのconfigクラスがそれを設定します。 –

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に追加する必要があるためです。そのうちの1つがnullの場合、予期しない結果につながります。 – mokuril

0

ミッコの答えは働きました美しく。私がする必要があった変更は: の代わりに: cq.select(得意先) .where(predicates.toArray(new Predicate [] {})); REPLACED WITH: 述語[] predicatesarr = predicates.toArray(新しい述語[述語。サイズ()]); cq.select(顧客).where(predicatesarr);

どこか元のリストから配列への変換が機能しませんでした。

関連する問題