java JPA2 Criteria API 更可取的真实世界示例有哪些?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3420752/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are some of the real world example where JPA2 Criteria API is more preferable?
提问by Joshua Partogi
I have taken a look at JPA 2.0 Criteria API, but I found it to be too cumbersome unlike Hibernate Criteria. Is there any good reason to use JPA 2.0 Criteria API rather than using JPA-QL? Thanks for your advise.
我已经查看了 JPA 2.0 Criteria API,但我发现它与 Hibernate Criteria 不同,它太麻烦了。是否有充分的理由使用 JPA 2.0 Criteria API 而不是使用 JPA-QL?感谢您的意见。
回答by Pascal Thivent
Like the Hibernate Criteria API, the JPA 2.0 Criteria API is especially nice to build queries dynamically, to handle cases where the query structure varies depending upon runtime conditions.
与 Hibernate Criteria API 一样,JPA 2.0 Criteria API 特别适合动态构建查询,以处理查询结构因运行时条件而异的情况。
But there is more. While being more verbose than Hibernate's Criteria API, the JPA Criteria API allows to build typesafequeries (if you use the Metamodel API). Below an example:
但还有更多。虽然比 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();
In the above snippet, the following would raise a compilation error for example:
在上面的代码片段中,以下代码会引发编译错误,例如:
Predicate condition = qb.gt(p.get(Person_.age, "xyz"));
In case you wonder, Person_is the static, instantiated, canonical metamodel classcorresponding to the original Personentity class (generated by an annotation processor). It provides a strongly typed alternative to a runtime reflection based approach:
在你想知道的情况下,Person_是静态的,实例化,规范元模型类对应于原始Person实体类(由注释处理器生成)。它为基于运行时反射的方法提供了强类型替代方案:
Field field = Person.class.getField("age");
Pros:
优点:
- Type safety, compile time verification!
- Prohibits the construction of queries that are syntactically incorrect.
- Can raise a compilation error after a refactoring.
- Provides out of the box support for auto-completion
- Better suited for dynamic queries.
- 类型安全,编译时验证!
- 禁止构造语法错误的查询。
- 重构后可能会引发编译错误。
- 为自动完成提供开箱即用的支持
- 更适合动态查询。
Cons:
缺点:
- More verbose.
- Less readable.
- 比较啰嗦。
- 可读性较差。
I feel in general more comfortable with JPQL but the type safety of the Criteria API is a major difference with JPQL (and also the Hibernate Criteria API).
总的来说,我觉得 JPQL 更舒服,但 Criteria API 的类型安全是与 JPQL(以及 Hibernate Criteria API)的主要区别。
See also
也可以看看
- Using the Criteria API and Metamodel API to Create Basic Type-Safe Queries
- Dynamic, typesafe queries in JPA 2.0
- Comparing JPQL, Criteria string-based and typesafe queries
- A typesafe criteria query API for JPA
- 使用 Criteria API 和 Metamodel API 创建基本的类型安全查询
- JPA 2.0 中的动态类型安全查询
- 比较 JPQL、Criteria 基于字符串和类型安全的查询
- JPA 的类型安全条件查询 API
Related answers
相关回答
回答by Arthur Ronald
JPA 2.0 Criteria API is The Object-based API for building queries. I think it can play a good job when you have a dynamic querywhich can become more readableas follows
JPA 2.0 Criteria API 是用于构建查询的基于对象的 API。我认为当你有一个动态查询时它可以发挥很好的作用,它可以变得更具可读性,如下所示
cq.select(...)
.where(...)
.orderBy(...)
.groupBy(...);
But when using staticquery prefer To use an externalized, maintainable and readablefile
但是当使用静态查询时更喜欢使用外部化的、可维护的和可读的文件
<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>
If you have a modularized application use one xml file for each module as follows
如果您有一个模块化的应用程序,请为每个模块使用一个 xml 文件,如下所示
br
com
ar
moduleA
model
repository
moduleA.xml
moduleB
model
repository
moduleB.xml
moduleC
model
repository
moduleC.xml
Then you define your mappinf-file element
然后你定义你的 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>
回答by Timo Westk?mper
JPA 2 Criteria can be used in statically typed form if you generate the entity metamodel. It is more verbose than JPQL, but is statically typed and supports dynamic query construction directly.
如果您生成实体元模型,则可以以静态类型形式使用 JPA 2 标准。它比 JPQL 更冗长,但是是静态类型的并且直接支持动态查询构造。
The benefits of a statically typed query language is that you can catch more errors at compile time and IDE features like autocomplete can be used as well.
静态类型查询语言的好处是您可以在编译时捕获更多错误,并且还可以使用自动完成等 IDE 功能。
回答by Ivo Limmen
For me the real world example where JPA2 shines is in when you need to create a query based on input from a user. I am not talking about a very simple where with one parameter. I mean when you have made an advanced search option in your application. One that requires joins when a certain parameter is filled. You don't what to concatenate your HQL or SQL to include a large set of parameters, extra joins and functions. Custom SQL requires a lot of tests to prove it works. Adding extra search options to HQL and SQL requires a lot of rework whereas this might be simpler in JPA.
对我来说,当您需要根据用户的输入创建查询时,JPA2 大放异彩的真实世界示例就在其中。我不是在谈论一个非常简单的带有一个参数的地方。我的意思是当您在应用程序中设置高级搜索选项时。当某个参数被填充时需要连接的一个。您不需要连接 HQL 或 SQL 以包含大量参数、额外的连接和函数。自定义 SQL 需要进行大量测试才能证明其有效。向 HQL 和 SQL 添加额外的搜索选项需要大量返工,而这在 JPA 中可能更简单。

