原文地址: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 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:
<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.
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();
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:
-
Holding the cached query results
-
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.
org.hibernate.cache.internal.StandardQueryCache
org.hibernate.cache.spi.UpdateTimestampsCache
If you configure your underlying cache implementation to use expiration, it’s very important that the timeout of the underlying cache region for the In fact, we recommend that the |
If you require fine-grained control over query cache expiration policies, you can specify a named cache region for a particular query.
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();
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.
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();
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 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
|