11 个 JPA 和 Hibernate 查询提示

在开始介绍提示列表之前,让我们快速了解一下如何使用查询提示。

JPA 和 Hibernate 支持一组提示,您可以使用它们向对你的持久保存提供附加信息以影响查询的执行。您可以将它们用于许多不同的事情,例如为查询设置超时、使用实体图或定义查询结果的缓存。您可以将提示提供给EntityManager.find方法、命名查询和临时查询的 Query接口或@NamedQuery的定义。

唯一令人遗憾的是它们每个的语法都有点不同。

EntityManager.find方法接受HashMap<String , Object>作为附加参数来提供提示。

EntityGraph<?> graph = em.getEntityGraph(“graph.AuthorBooks”);
 
HashMap<String, Object> properties = new HashMap<>();
properties.put(“javax.persistence.fetchgraph”, graph);
 
em.find(Author.class, 1L, properties);

Query 接口提供了setHint(String name, Object value)方法,您必须为要提供的每个提示调用该方法。

EntityGraph<?> graph = em.getEntityGraph(“graph.AuthorBooks”);
 
em.createQuery(“SELECT a FROM Author a”)
  .setHint(“javax.persistence.fetchgraph”, graph)
.getResultList();

还可以向@NamedQuery注释提供提示,以将它们添加到命名查询的定义中。

@NamedQuery(name = “selectAuthors”, query = “SELECT a FROM Author a”, 
hints = @QueryHint(name = QueryHints.COMMENT, value = “a custom SQL comment”))

在这种情况下,提示将用于此命名查询的每个实例,您不必在查询接口上设置它们。

em.createNamedQuery(“selectAuthors”).getResultList();


JPA提示
让我们从 JPA 规范定义的提示开始:

1. javax.persistence.lock.timeout(长- 毫秒)
此提示定义获取悲观锁的超时(以毫秒为单位)。

2. javax.persistence.query.timeout(长- 毫秒)
javax.persistence.query.timeout提示定义查询在被取消之前允许运行的时间。Hibernate 本身不处理此超时,而是通过 JDBC Statement.setTimeout方法将其提供给 JDBC 驱动程序。

3. javax.persistence.cache.retrieveMode(CacheRetrieveMode – 使用 | 绕过)
retrieveMode提示支持USE和BYPASS值,并告诉 Hibernate 是否应使用二级缓存来检索实体,或者是否应绕过它并直接从数据库获取实体。

4. javax.persistence.cache.storeMode(CacheStoreMode – 使用|绕过|刷新)
该提示定义了 Hibernate 如何将更改的实体写入二级缓存。它可以使用缓存将实体添加到缓存并更新现有实体,或者对尚未存储在缓存中的实体绕过它,仅更新现有实体,或者在从缓存中检索实体之前刷新位于缓存中的实体。

5. javax.persistence.loadgraph(EntityGraph)
javax.persistence.loadgraph提示允许您提供实体图作为查询的负载图,以专门为此查询定义急切获取。

6. javax.persistence.fetchgraph(EntityGraph)
您可以使用此提示提供实体图作为查询的 fetchgraph。

Hibernate 提示
这些是 JPA 规范定义的最重要的查询提示。让我们继续讨论 Hibernate 特定的部分。

7. org.hibernate.flushMode(FlushMode – 自动|始终|提交|手动)
如果您修改一个实体,Hibernate 会将这些更改保留在第一级缓存中,直到它被刷新。默认情况下,这发生在每个查询之前,但您可以通过提供org.hibernate.FlushMode枚举的值作为org.hibernate.flushMode提示来控制它。您可以选择:

AUTO = Hibernate 决定是否必须将更改写入数据库,
ALWAYS = 每次查询之前会话都会被刷新,
COMMIT = Hibernate 在事务提交之前不会将任何更改写入数据库,
手动=您必须自己刷新会话。

8. org.hibernate.readOnly (布尔值)
如果您不打算对所选实体应用任何更改,则可以将org.hibernate.readOnly提示设置为 true。这允许 Hibernate 停用这些实体的脏检查,并可以提供性能优势。

9. org.hibernate.fetchSize ( Long – 记录数)
Hibernate 向 JDBC 驱动程序提供此提示的值,以定义驱动程序应在一批中接收的行数。如果驱动程序支持的话,这可以改善 JDBC 驱动程序和数据库之间的通信。

10. org.hibernate.comment(字符串——自定义注释)
如果将 persistence.xml文件中的hibernate.use_sql_comments属性设置为 true,Hibernate 会为每个查询生成一条注释并将其写入日志文件。如果您必须分析巨大或复杂的 SQL 日志,这可能很有用。

您可以使用org.hibernate.comment提示为查询提供您自己的注释。

11. org.hibernate.cacheable
如果要使用 Hibernate 的查询缓存,则必须在persistence.xml文件中激活它,并通过将org.hibernate.cacheable提示设置为 true 来为特定查询启用它。

概括
正如您所看到的,JPA 和 Hibernate 提供了一组提示,您可以使用它们来自定义和优化查询的执行。特别是与缓存和实体图相关的那些可以为您的应用程序提供巨大的性能优势。