2

我很好奇为什么使用CriteriaBuilderJPA 2 类可以创建这样的查询。假设我有一个名为as 属性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属性是 a String。为什么我可以编译这样的废话,将 aString与 double 进行比较?换句话说,为什么被调用equal方法的签名是这样的:

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

而不是如下可能更安全的版本?

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

像Querydsl这样的其他查询框架会为这个问题提供更好的解决方案吗?

4

2 回答 2

2

特定于 JPA,您还可以使用不需要编译时模型生成的对象查询鱼雷查询(但这是专门针对 HQL)。无论如何QueryDsl是第一个实现类型安全查询的

于 2013-10-09T16:16:43.060 回答
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 回答