And*_*rey 15 java caching hibernate jpa
我正在使用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步和第2步应该在每个应用程序生命周期内执行一次.但是怎么做呢?换句话说,我需要缓存Query实例.
当然我可以在我身边实现这样的缓存.但是等等,我正在使用现代强大的ORM!他们不是已经为我做了这个吗?
请注意,我没有提到像Hibernate查询缓存那样缓存查询结果的东西.在这里,我想更快地执行我的查询.
Pas*_*ent 18
使用静态定义的命名查询.它们更有效,因为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 {
...
}
Run Code Online (Sandbox Code Playgroud)
还建议使用实体名称为命名查询添加前缀(以获得某种名称空间并避免冲突).
然后在DAO中:
class OrderDao {
EntityManager em;
List getOrders(Long customerId) {
return em.createNamedQuery("Order.findByCustomerId")
.setParameter("customerId", customerId);
.getResultList();
}
}
Run Code Online (Sandbox Code Playgroud)
PS:我重复使用你建议作为例子的查询但是有点奇怪的customerId是Order,我希望有一个Customer.
这是Hibernate中的查询计划缓存.因此,每次调用DAO时都不会解析HQL(因此#1在应用程序生命周期中只出现一次).这是QueryPlanCache.它没有大量记录,因为它"正常".但你可以在这里找到更多信息.
| 归档时间: |
|
| 查看次数: |
19562 次 |
| 最近记录: |