有哪些现实世界的例子,更优选JPA2 Criteria API?

时间:2010-08-06 02:59:50

标签: java hibernate jpa jpa-2.0

我已经看过JPA 2.0 Criteria API,但我发现它与Hibernate Criteria不同,太麻烦了。是否有充分的理由使用JPA 2.0 Criteria API而不是使用JPA-QL?谢谢你的建议。

4 个答案:

答案 0 :(得分:36)

与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)的主要区别在于。

另见

相关答案

答案 1 :(得分:4)

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文件元素

<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>

答案 2 :(得分:1)

如果生成实体元模型,JPA 2 Criteria可以以静态类型形式使用。它比JPQL更冗长,但是是静态类型的,并且直接支持动态查询构造。

静态类型查询语言的好处是可以在编译时捕获更多错误,也可以使用自动完成等IDE功能。

答案 3 :(得分:0)

对我来说,当你需要根据用户的输入创建一个查询时,JPA2会发光的真实世界示例。我不是在谈论一个非常简单的参数。我的意思是你在应用程序中创建了一个高级搜索选项。在填充某个参数时需要连接的一个。您不需要连接HQL或SQL以包含大量参数,额外连接和函数。自定义SQL需要大量测试才能证明它有效。为HQL和SQL添加额外的搜索选项需要大量的返工,而这在JPA中可能更简单。