Hibernate查询缓存

原文地址:http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#caching-query

13.5. Query cache

Aside from caching entities and collections, Hibernate offers a query cache too. This is useful for frequently executed queries with fixed parameter values.

Caching of query results introduces some overhead in terms of your applications normal transactional processing. For example, if you cache results of a query against Person, Hibernate will need to keep track of when those results should be invalidated because changes have been committed against any Person entity.

That, coupled with the fact that most applications simply gain no benefit from caching query results, leads Hibernate to disable caching of query results by default.

To use query caching, you will first need to enable it with the following configuration property:

Example 287. Enabling query cache
<property
    name="hibernate.cache.use_query_cache"
    value="true" />

As mentioned above, most queries do not benefit from caching or their results. So by default, individual queries are not cached even after enabling query caching. Each particular query that needs to be cached must be manually set as cacheable. This way, the query looks for existing cache results or adds the query results to the cache when being executed.

Example 288. Caching query using JPA
List<Person> persons = entityManager.createQuery(
    "select p " +
    "from Person p " +
    "where p.name = :name", Person.class)
.setParameter( "name", "John Doe")
.setHint( "org.hibernate.cacheable", "true")
.getResultList();
Example 289. Caching query using Hibernate native API
List<Person> persons = session.createQuery(
    "select p " +
    "from Person p " +
    "where p.name = :name")
.setParameter( "name", "John Doe")
.setCacheable(true)
.list();

The query cache does not cache the state of the actual entities in the cache; it caches only identifier values and results of value type.

Just as with collection caching, the query cache should always be used in conjunction(结合) with the second-level cache for those entities expected to be cached as part of a query result cache.

13.5.1. Query cache regions

This setting creates two new cache regions:

org.hibernate.cache.internal.StandardQueryCache

Holding the cached query results

org.hibernate.cache.spi.UpdateTimestampsCache

Holding timestamps of the most recent updates to queryable tables. These are used to validate the results as they are served from the query cache.

If you configure your underlying cache implementation to use expiration, it’s very important that the timeout of the underlying cache region for the UpdateTimestampsCache is set to a higher value than the timeouts of any of the query caches.

In fact, we recommend that the UpdateTimestampsCache region is not configured for expiration (time-based) or eviction (size/memory-based) at all. Note that an LRU (Least Recently Used) cache eviction policy is never appropriate for this particular cache region.

If you require fine-grained control over query cache expiration policies, you can specify a named cache region for a particular query.

Example 290. Caching query in custom region using JPA
List<Person> persons = entityManager.createQuery(
        "select p " +
        "from Person p " +
        "where p.id > :id", Person.class)
        .setParameter( "id", 0L)
        .setHint( QueryHints.HINT_CACHEABLE, "true")
        .setHint( QueryHints.HINT_CACHE_REGION, "query.cache.person" )
        .getResultList();
Example 291. Caching query in custom region using Hibernate native API
List<Person> persons = session.createQuery(
    "select p " +
    "from Person p " +
    "where p.id > :id")
.setParameter( "id", 0L)
.setCacheable(true)
.setCacheRegion( "query.cache.person" )
.list();

If you want to force the query cache to refresh one of its regions (disregarding(忽视) any cached results it finds there), you can use custom cache modes.

Example 292. Using custom query cache mode with JPA
List<Person> persons = entityManager.createQuery(
    "select p " +
    "from Person p " +
    "where p.id > :id", Person.class)
.setParameter( "id", 0L)
.setHint( QueryHints.HINT_CACHEABLE, "true")
.setHint( QueryHints.HINT_CACHE_REGION, "query.cache.person" )
.setHint( "javax.persistence.cache.storeMode", CacheStoreMode.REFRESH )
.getResultList();
Example 293. Using custom query cache mode with Hibernate native API
List<Person> persons = session.createQuery(
    "select p " +
    "from Person p " +
    "where p.id > :id")
.setParameter( "id", 0L)
.setCacheable(true)
.setCacheRegion( "query.cache.person" )
.setCacheMode( CacheMode.REFRESH )
.list();

When using CacheStoreMode.REFRESH or CacheMode.REFRESH in conjunction with the region you have defined for the given query, Hibernate will selectively force the results cached in that particular region to be refreshed.

This is particularly useful in cases where underlying data may have been updated via a separate process and is a far more efficient alternative to bulk eviction of the region via SessionFactory eviction which looks as follows:

session.getSessionFactory().getCache().evictQueryRegion( "query.cache.person" );

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页