39

複数のパラメーターを持つ JPA Criteria API を使用する検索メソッドを作成する必要があります。問題は、すべてのパラメーターが必須ではないということです。そのため、一部は null になる可能性があり、クエリに含めるべきではありません。CriteriaBuilder でこれを試してみましたが、機能させる方法がわかりませんでした。

Hibernate Criteria API を使用すると、これはかなり簡単です。基準を作成してから、制限を追加するだけです。

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

JPAのCriteria APIで同じことを達成するにはどうすればよいですか?

4

5 に答える 5

95

コンセプトは、使用したい述語のみを含む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();
于 2012-08-30T15:04:46.103 に答える
7

このサイトJPA Criteria APIを見てください。たくさんの例があります。

更新: 具体例の提供

残高が特定の値よりも低いアカウントを検索してみましょう。

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

ところで: entityManager は EJB/Service/DAO のどこかに注入されます。

于 2012-08-30T14:50:20.800 に答える
2

ミッコの答えは見事に機能しました。私がする必要があった唯一の変更は、次のものを置き換えることでした:

cq.select(customer).where(predicates.toArray(new Predicate[]{}));

と:

Predicate [] predicatesarr = predicates.toArray(new Predicate[predicates.size()]); 
cq.select(customer).where(predicatesarr);

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

于 2016-10-10T05:16:46.747 に答える