2

CriteriaBuilderJPA 2のクラスを使用して、なぜこのようなクエリを作成できるのか興味があります。属性として呼び出されるUser永続化されたクラスがあるとします。なぜ私はこれを書くことができますか?Stringname

CriteriaBuilder builder = mgr.getCriteriaBuilder();

CriteriaQuery<User> crit = builder.createQuery(User.class);
Root<User> user = crit.from(User.class);                     // 1
crit.select(user)
    .where(builder.equal(user.get(User_.name), 2.5));        // 2

まず、マーカー1で:なぜUser.classもう一度指示する必要があるのですか?私のCriteriaQueryは、とにかくユーザーに興味があることを知っているはずではありませんか?ここに別のクラスを注入することは、型安全性を損なうのではないでしょうか?

次に、マーカー2で:nameプロパティはStringStringaをdoubleと比較して、なぜこのようなナンセンスをコンパイルできるのですか?言い換えると、呼び出されたequalメソッドのシグネチャが次のようになるのはなぜですか。

public Predicate equal(Expression<?> x, Object y)

次のようにおそらくよりタイプセーフなバージョンの代わりに?

public <T> Predicate equal(Expression<T> x, T y)

Querydslのような他のクエリフレームワークは、この問題に対するより良い解決策を提供しますか?

4

2 に答える 2

2

JPA 2 Criteria APIのタイプセーフな側面は、仕様プロセスのかなり遅い時点で追加されたと思います。それが一貫性を感じない理由です。

Querydslは、JPA 2 Criteria APIよりも簡潔であり、タイプセーフでもあります。Querydslは、述語の作成にファクトリクラスの代わりに流暢なビルダーを使用するため、同等のメソッドはhttp://www.querydsl.com/static/querydsl/2.8.0/apidocs/com/mysema/query/types/exprにあります。 /SimpleExpression.html#eq%28T%29

私はQuerydslのメンテナーなので、この答えには偏りがあります。

于 2012-10-20T07:02:51.477 に答える
2

JPAに固有であり、コンパイル時モデルの生成を必要としないObjectQueryまたはTorpedoQuery(ただし、これはHQLに特化しています)も使用できます。とにかくQueryDslはタイプセーフクエリを実装した最初の1つです

于 2013-10-09T16:16:43.060 に答える