我查看了 JPA 2.0 Criteria API,但我发现它不像 Hibernate Criteria 那样繁琐。是否有充分的理由使用 JPA 2.0 Criteria API 而不是使用 JPA-QL?感谢您的意见。
4 回答
与 Hibernate Criteria API 一样,JPA 2.0 Criteria API 特别适合动态构建查询,以处理查询结构根据运行时条件而变化的情况。
但还有更多。虽然比 Hibernate 的 Criteria API 更冗长,但 JPA Criteria API 允许构建类型安全的查询(如果您使用 Metamodel API)。下面是一个例子:
EntityManager em = ...
QueryBuilder qb = em.getQueryBuilder();
CriteriaQuery<Person> c = qb.createQuery(Person.class);
Root<Person> p = c.from(Person.class);
Predicate condition = qb.gt(p.get(Person_.age), 20);
c.where(condition);
TypedQuery<Person> q = em.createQuery(c);
List<Person> result = q.getResultList();
在上面的代码片段中,以下代码会引发编译错误,例如:
Predicate condition = qb.gt(p.get(Person_.age, "xyz"));
如果您想知道,Person_
是对应于原始实体类(由注释处理器生成)的静态、实例化、规范元模型类。Person
它为基于运行时反射的方法提供了一个强类型的替代方案:
Field field = Person.class.getField("age");
优点:
- 类型安全,编译时验证!
- 禁止构造语法不正确的查询。
- 重构后可能会引发编译错误。
- 为自动完成提供开箱即用的支持
- 更适合动态查询。
缺点:
- 更冗长。
- 可读性较差。
总的来说,我觉得 JPQL 更舒服,但 Criteria API 的类型安全性是与 JPQL(以及 Hibernate Criteria API)的主要区别。
也可以看看
- 使用 Criteria API 和 Metamodel API 创建基本的类型安全查询
- JPA 2.0 中的动态类型安全查询
- 比较 JPQL、Criteria 基于字符串和类型安全的查询
- JPA 的类型安全标准查询 API
相关答案
JPA 2.0 Criteria API 是用于构建查询的基于对象的 API。我认为当你有一个动态查询时它可以发挥很好的作用,它可以变得更具可读性,如下所示
cq.select(...)
.where(...)
.orderBy(...)
.groupBy(...);
但是在使用静态查询时更喜欢使用外部化、可维护和可读的文件
<entity-mappings>
...
<named-query name="ORDER">
<query>
<![CDATA[
from
Order
]]>
</query>
</named-query>
<named-query name="ORDER_WITH_LINE_ITEM">
<query>
<![CDATA[
from
Order o
inner join fetch
o.lineItemList
]]>
</query>
</named-query>
...
</entity-mappings>
如果您有一个模块化应用程序,请为每个模块使用一个 xml 文件,如下所示
br
com
ar
moduleA
model
repository
moduleA.xml
moduleB
model
repository
moduleB.xml
moduleC
model
repository
moduleC.xml
然后你定义你的 mappinf-file 元素
<mapping-file>br/com/ar/moduleA/model/repository/moduleA.xml</mapping-file>
<mapping-file>br/com/ar/moduleB/model/repository/moduleB.xml</mapping-file>
<mapping-file>br/com/ar/moduleC/model/repository/moduleC.xml</mapping-file>
如果您生成实体元模型,则 JPA 2 Criteria 可以以静态类型的形式使用。它比 JPQL 更冗长,但是是静态类型的,并且直接支持动态查询构造。
静态类型查询语言的好处是您可以在编译时捕获更多错误,并且还可以使用自动完成等 IDE 功能。
对我来说,当您需要根据用户的输入创建查询时,JPA2 大放异彩的真实示例就出现了。我不是在谈论一个非常简单的地方,只有一个参数。我的意思是当您在应用程序中设置了高级搜索选项时。填充某个参数时需要连接的一种。您不需要连接您的 HQL 或 SQL 以包含大量参数、额外的连接和函数。自定义 SQL 需要大量测试来证明它有效。向 HQL 和 SQL 添加额外的搜索选项需要大量返工,而在 JPA 中这可能更简单。