我应该使用@NamedQuery 注释还是addNamedQuery 方法?
Should I use @NamedQuery annotation or addNamedQuery method?
目前,构成我的应用程序的 JPA 实体有一个 @NamedQueries 块,其中包含许多 @NamedQuery 注释。这很好用,但我的一些实体有超过 80 个 @NamedQuery 注释并且越来越难以维护。我现在需要向我的查询添加排序并且不想创建额外的@NamedQuery 注释。
在研究过程中,我发现了 JPA 2.1 EntityManagerFactory.addNamedQuery 方法。这似乎是我祈祷的答案。我可以创建一个在启动时运行的初始化程序,以使用我建立的命名约定创建我所有的命名查询,并消除实体顶部的大 @NamedQueries 块。
我什至可以使用以下 EclipseLink 特定代码来添加基于现有 NamedQuery 的新 NamedQuery。
TypedQuery<Portrait> tq = em.createNamedQuery("Portraits.read", Portrait.class);
String jpql = tq.unwrap(EJBQueryImpl.class).getDatabaseQuery().getJPQLString();
Query q = this.em.createQuery(jpql + " ORDER BY p.id DESC");
em.getEntityManagerFactory().addNamedQuery("Portraits.read.Id-D", q);
TypedQuery<Portrait> tq2 = em.createNamedQuery("Portraits.read.Id-D", Portrait.class);
有什么理由,我不应该使用 addNamedQuery 方法来代替或补充 @NamedQuery 注释?
命名查询用于组织查询定义和提高应用程序性能,因为查询字符串是在注释中定义的,不能在运行时更改,还可以防止 sql 注入等安全问题。
- NamedQuery 的名称作用域为整个持久化单元
并且在该范围内必须是唯一的。所以也许最好定义
正如你所说,它给每个 class。因为它是未定义的应该
如果同一持久性单元中的两个查询具有相同的
名称,但很可能是应用程序的部署
将失败或一个将覆盖另一个,导致不可预测
运行时的结果。
动态命名查询 (addNamedQuery) 是一种混合方法
动态创建查询,然后将其保存为命名查询
实体经理工厂。在那一点上,它变得和其他任何东西一样
可能已在元数据中静态声明的命名查询。
这仅在少数特定情况下有用:
它提供的主要优点是如果有查询直到运行时才知道,但随后重复发出。
一旦动态查询成为命名查询,它只承担处理一次的成本。是在查询注册为命名查询时支付费用,还是推迟到第一次执行时支付,具体取决于具体实现。
总而言之,最好在与查询结果最直接对应的实体 class 上定义命名查询。但动态查询在某些特定点也有它们的位置。
目前,构成我的应用程序的 JPA 实体有一个 @NamedQueries 块,其中包含许多 @NamedQuery 注释。这很好用,但我的一些实体有超过 80 个 @NamedQuery 注释并且越来越难以维护。我现在需要向我的查询添加排序并且不想创建额外的@NamedQuery 注释。
在研究过程中,我发现了 JPA 2.1 EntityManagerFactory.addNamedQuery 方法。这似乎是我祈祷的答案。我可以创建一个在启动时运行的初始化程序,以使用我建立的命名约定创建我所有的命名查询,并消除实体顶部的大 @NamedQueries 块。
我什至可以使用以下 EclipseLink 特定代码来添加基于现有 NamedQuery 的新 NamedQuery。
TypedQuery<Portrait> tq = em.createNamedQuery("Portraits.read", Portrait.class);
String jpql = tq.unwrap(EJBQueryImpl.class).getDatabaseQuery().getJPQLString();
Query q = this.em.createQuery(jpql + " ORDER BY p.id DESC");
em.getEntityManagerFactory().addNamedQuery("Portraits.read.Id-D", q);
TypedQuery<Portrait> tq2 = em.createNamedQuery("Portraits.read.Id-D", Portrait.class);
有什么理由,我不应该使用 addNamedQuery 方法来代替或补充 @NamedQuery 注释?
命名查询用于组织查询定义和提高应用程序性能,因为查询字符串是在注释中定义的,不能在运行时更改,还可以防止 sql 注入等安全问题。
- NamedQuery 的名称作用域为整个持久化单元 并且在该范围内必须是唯一的。所以也许最好定义 正如你所说,它给每个 class。因为它是未定义的应该 如果同一持久性单元中的两个查询具有相同的 名称,但很可能是应用程序的部署 将失败或一个将覆盖另一个,导致不可预测 运行时的结果。
动态命名查询 (addNamedQuery) 是一种混合方法 动态创建查询,然后将其保存为命名查询 实体经理工厂。在那一点上,它变得和其他任何东西一样 可能已在元数据中静态声明的命名查询。
这仅在少数特定情况下有用:
它提供的主要优点是如果有查询直到运行时才知道,但随后重复发出。
一旦动态查询成为命名查询,它只承担处理一次的成本。是在查询注册为命名查询时支付费用,还是推迟到第一次执行时支付,具体取决于具体实现。
总而言之,最好在与查询结果最直接对应的实体 class 上定义命名查询。但动态查询在某些特定点也有它们的位置。