Java JPA 为什么使用 createNamedQuery

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/832755/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:00:07  来源:igfitidea点击:

JPA why use createNamedQuery

javahibernatejpadata-access-layer

提问by Ruggs

I'm in the processes of changing my DAO layer from using Hibernate API to using a pure JPA API implementation. It looks like the recommended method is to use the createNamedQuery from the entity manager. The named queries are stored in annotations in the model/entity classes. This just not makes sense to me. Why would you define the JPA Queries in the model objects but use them in the DAOs. Wouldn't it make more sense to just use createQuery from within the DAO itself and define the queries in the DAO or even just define the named queries in the DAO itself?

我正在将我的 DAO 层从使用 Hibernate API 更改为使用纯 JPA API 实现。看起来推荐的方法是使用实​​体管理器中的 createNamedQuery。命名查询存储在模型/实体类的注释中。这对我来说没有意义。为什么要在模型对象中定义 JPA 查询,但在 DAO 中使用它们。仅在 DAO 本身中使用 createQuery 并在 DAO 中定义查询,或者甚至仅在 DAO 本身中定义命名查询不是更有意义吗?

For those of you that have implemented your DAO layer using the JPA API how have you defined your queries?

对于那些使用 JPA API 实现了 DAO 层的人,您是如何定义查询的?

采纳答案by cletus

I use named queries.

我使用命名查询。

There are two reasons to do so:

这样做有两个原因:

  1. It puts them in a more central place rather than scattered in code with random createQuery() calls; and
  2. Build processes can validate the queries (really useful).
  1. 它将它们放在更中心的位置,而不是通过随机的 createQuery() 调用分散在代码中;和
  2. 构建过程可以验证查询(非常有用)。

回答by topchef

I had experience completely opposite to the one of cletus - I found no benefit and also found them awkward to use. Trivial queries would make no difference where to define, but non-trivial queries are usually hard to associate with any single entity but easy with business-oriented method.

我的经历与 cletus 完全相反 - 我没有发现任何好处,并且还发现它们使用起来很尴尬。平凡查询在何处定义没有区别,但非平凡查询通常很难与任何单个实体相关联,但使用面向业务的方法却很容易。

If you use more or less sophisticated infrastructure in DAOs (for re-use and consistency) then usage of named queries tend to complicate both implementation and readability with no apparent benefit to offer.

如果您在 DAO 中使用或多或少复杂的基础设施(为了重用和一致性),那么命名查询的使用往往会使实现和可读性复杂化,而且没有明显的好处。

Validating of queries by build process sounds interesting - I would like to know more what it really means... My queries leave little margin for error since every DAO method is unit tested as much as it makes sense.

通过构建过程验证查询听起来很有趣 - 我想知道更多它的真正含义......我的查询几乎没有错误余地,因为每个 DAO 方法都经过单元测试,因为它很有意义。

回答by Adeel Ansari

Don't just use named queries everywhere, there are cases where they are not appropriate, such as when its gonna be rarely used queries then it may be more efficient when built on as needed basis.

不要只是在任何地方都使用命名查询,在某些情况下它们是不合适的,例如当它很少使用查询时,在根据需要构建时可能会更有效。

Named queries make more sense when its gonna be complex and got executed frequently.

当命名查询很复杂并且经常执行时,它会更有意义。

[Updated]

[更新]

You can write the named queries at mapping, instead.

相反,您可以在映射时编写命名查询。

回答by Oliver Drotbohm

You could take a look at Spring Data JPA. It allows you to simply define an interface and execute queries without the need to implement the execution manually.

你可以看看Spring Data JPA。它允许您简单地定义一个接口并执行查询,而无需手动实现执行。

Entity:

实体:

@Entity
@NamedQuery(id="User.findByLastname" query="from User u where u.lastname = ?1")
public class User implements Persistable<Long> {

  @Id
  private Long id;
  private String username;
  private String lastname;
  private int age;
}

Repository:

存储库:

public interface UserRepository extends CrudRepository<User, Long> {

  // Will trigger the NamedQuery due to a naming convention
  List<User> findByLastname(String lastname);

  // Will create a query from the methodname
  // from User u where u.username = ?
  User findByUsername(String username);

  // Uses query annotated to the finder method in case you
  // don't want to pollute entity with query info
  @Query("from User u where u.age > ?1")
  List<User> findByAgeGreaterThan(int age);
}

Setup:

设置:

EntityManager em = Persistence.getEntityManagerFactory().createEntityManager();
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);

UserRepository repository = factory.getRepository(UserRepository.class);

As you see you can choose between different ways to derive the query to be executed from the method. While deriving it directly from the method name is feasible for simple queries you'd probably choose between the @NamedQuery(JPA standard) or @Query(Spring Data JPA annotation) dependening on how much you like to stick with standards.

如您所见,您可以选择不同的方式来派生要从该方法执行的查询。虽然直接从方法名称派生它对于简单查询是可行的,但您可能会根据您对标准的坚持程度在@NamedQuery(JPA 标准)或@Query(Spring Data JPA 注释)之间进行选择。

Spring Data JPA gives you support in various other corners of data access layer implementation, allows providing custom implementations for methods and nicely integrates with Spring.

Spring Data JPA 在数据访问层实现的各个其他方面为您提供支持,允许为方法提供自定义实现并与 Spring 很好地集成。

回答by Jim Barrows

Embrace the power of and :) If you have a query that makes sense to put into the model, do so. If you don't, don't. It might be even better to ask "Why are you writing DAO's with JPS?" If the answer is to "Isolate my code from the database." This is done by the library implementing JPA. If the answer is "to isolate my code from changes to the way I persist things", then JPA does that by allowing you to have different implementations. I use query objects for complex queries, and still used named queries where possible, and I like the fact that named queries get compiled, and so I find bugs in them that much faster. I have no DAO layer.

拥抱 and 的力量 :) 如果您有一个可以放入模型的查询,请这样做。如果你不这样做,不要。问“你为什么用 JPS 编写 DAO?”可能会更好。如果答案是“将我的代码与数据库隔离”。这是由实现 JPA 的库完成的。如果答案是“将我的代码与我持久化的方式的更改隔离开来”,那么 JPA 通过允许您拥有不同的实现来做到这一点。我将查询对象用于复杂查询,并在可能的情况下仍然使用命名查询,我喜欢命名查询被编译的事实,因此我更快地发现其中的错误。我没有 DAO 层。