代码之家  ›  专栏  ›  技术社区  ›  Joshua Partogi

在现实世界中,JPA2标准API更可取的例子有哪些?

  •  24
  • Joshua Partogi  · 技术社区  · 14 年前

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

    4 回复  |  直到 9 年前
        1
  •  36
  •   Community Mofi    7 年前

    与Hibernate标准API一样,JPA2.0标准API特别适合构建查询。 动态地 ,以处理查询结构因运行时条件而异的情况。

    但还有更多。虽然比Hibernate的标准API更详细,但JPA标准API允许构建 类型安全 查询(如果使用元模型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更适合,但是标准API的类型安全性与JPQL(以及Hibernate标准API)有很大的区别。

    也见

    相关答案

        2
  •  4
  •   Arthur Ronald    14 年前

    JPA2.0标准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
    

    然后定义mapinf文件元素

    <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>
    
        3
  •  1
  •   Timo Westkämper    11 年前

    如果生成实体元模型,则可以在静态类型形式中使用JPA2标准。它比JPQL更详细,但是是静态类型的,并且直接支持动态查询构造。

    静态类型查询语言的好处在于,您可以在编译时捕获更多的错误,并且还可以使用诸如autocomplete之类的IDE功能。

        4
  •  0
  •   Ivo Limmen    9 年前

    对于我来说,当您需要基于用户的输入创建查询时,jpa2发光的现实世界示例就在这里。我说的不是一个非常简单的带有一个参数的where。我的意思是当你在你的应用程序中做了一个高级搜索选项。当某个参数被填充时需要连接的一种。您不需要连接您的HQL或SQL来包含大量参数、额外的联接和函数。自定义SQL需要大量的测试来证明它的有效性。向hql和sql添加额外的搜索选项需要大量的修改,而这在jpa中可能更简单。