gpt4 book ai didi

java - JPA:缓存查询

转载 作者:太空狗 更新时间:2023-10-29 22:50:47 28 4
gpt4 key购买 nike

我正在使用 JPA 在基于 Java EE 的 Web 应用程序中加载和保留实体。 Hibernate 用作 JPA 的实现,但我不使用 Hibernate 特定的功能,只使用纯 JPA。

这是一些 DAO 类,注意 getOrders 方法:

class OrderDao {  EntityManager em;  List getOrders(Long customerId) {    Query q = em.createQuery(      "SELECT o FROM Order o WHERE o.customerId = :customerId");    q.setParameter("customerId", customerId);    return q.getResultList();  }}

方法很简单,但有一个很大的缺点。每次调用该方法时,都会在 JPA 实现中的某处执行以下操作:

  1. JPQL 表达式被解析并编译为 SQL。
  2. 创建并初始化 Statement 或 PreparedStatement 实例。
  3. 语句实例填充参数并执行。

我认为上面的步骤 1 和 2 应该在每个应用程序生命周期中实现一次。但是怎么做呢?换句话说,我需要缓存 Query 实例。

当然我可以在我这边实现这样的缓存。但是等等,我正在使用现代强大的 ORM!他们不是已经为我做了这个吗?

请注意,我没有提到像 Hibernate 查询缓存这样的缓存查询结果的东西。在这里,我想更快地执行我的查询。

最佳答案

使用静态定义的命名查询。它们效率更高,因为 JPA 持久性提供程序可以在应用程序启动时将 JP QL 字符串转换为 SQL 一次,而不是每次执行查询时,特别推荐用于频繁执行的查询。

命名查询是使用 @NamedQuery 注解定义的,该注解通常用在结果的实体类上。在您的例子中,在 Order 实体上:

@Entity
@NamedQueries({
@NamedQuery(name="Order.findAll",
query="SELECT o FROM Order o"),
@NamedQuery(name="Order.findByPrimaryKey",
query="SELECT o FROM Order o WHERE o.id = :id"),
@NamedQuery(name="Order.findByCustomerId",
query="SELECT o FROM Order o WHERE o.customerId = :customerId")
})
public class Order implements Serializable {
...
}

还建议在命名查询前加上实体名称(以拥有某种 namespace 并避免冲突)。

然后在 DAO 中:

class OrderDao {
EntityManager em;

List getOrders(Long customerId) {
return em.createNamedQuery("Order.findByCustomerId")
.setParameter("customerId", customerId);
.getResultList();
}
}

PS:我重复使用了您作为示例建议的查询,但是在 Order 上有 customerId 有点奇怪,我希望有一个 Customer 相反。

引用资料

  • JPA 1.0 规范
    • 第 3.6.4 节“命名查询”

关于java - JPA:缓存查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3578711/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com