我很好奇为什么可以使用JPA2的CriteriaBuilder
类来创建这样的查询。假设我有一个User
类,属性是一个名为name
的持久化String
。为什么我可以写这篇文章?
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
属性是一个String
。为什么我可以像这样编译胡言乱语,将String
与double进行比较?换句话说,为什么调用的equal
方法的签名是这样的:
public Predicate equal(Expression<?> x, Object y)
而不是假设一个更类型安全的版本,如下所示?
public <T> Predicate equal(Expression<T> x, T y)
其他查询框架,如Querydsl,会为这个问题提供更好的解决方案吗?
发布于 2012-10-20 15:02:51
我相信JPA2Criteria API的类型安全方面是在规范过程的相当晚的时候添加的。这就是为什么感觉不一致的原因。
Querydsl比JPA2Criteria API更简洁,也更安全。Querydsl使用fluent构建器而不是工厂类来创建谓词,因此可以在http://www.querydsl.com/static/querydsl/2.8.0/apidocs/com/mysema/query/types/expr/SimpleExpression.html#eq%28T%29中找到等效的方法
我是Querydsl的维护者,所以这个答案是有偏见的。
发布于 2013-10-10 00:16:43
具体来说,在JPA上,您还可以使用不需要编译时模型生成的Object Query或Torpedo Query(但这在HQL上是专门的)。无论如何,QueryDsl是最先实现类型安全查询的一个
https://stackoverflow.com/questions/12981175
复制相似问题