缓存休眠本机查询 - 如何将特定查询的最大生存时间设置为生存时间?



嗨,我正在使用EHCache在JPA应用程序中缓存来自某些Hibernate本机查询的SQL结果。我想知道如何为特定查询设置结果应该缓存多长时间?即到 24 小时,但对于其他查询不是?

休眠属性

hibernate.dialect=org.hibernate.dialect.PostgreSQL95Dialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=none
hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory

EHCache Config XML

<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxEntriesLocalHeap="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxEntriesLocalDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
<persistence strategy="localTempSwap"/>
/>
</ehcache>

Spring 存储库类中的 Java 方法

@Repository
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class AnalyticsRepositoryImpl implements AnalyticsRepository {
public Map<Long, Long> getAgeStatistic(boolean onlyPaid) {
StringBuilder sb = new StringBuilder();
sb.append("SELECT (date_part('year',current_date) - date_part('year',a.date_value))  as age, COUNT(u.id) as count from answers a ");
sb.append("JOIN ...");
...
Query q = em.createNativeQuery(sb.toString());
// enable the cache for the native query
NativeQuery nativeQuery = q.unwrap(NativeQuery.class);
nativeQuery.addScalar("age", IntegerType.INSTANCE);
nativeQuery.addScalar("count", LongType.INSTANCE);
nativeQuery.setCacheable(true);
List<Object[]> result = q.getResultList();
// Place results in map
Map<Long, Long> map = convertResultSetToLongKeyMap(result);
return map;
}

我找到了答案,解决方案是使用"缓存区域"来解决我的问题。 因此,您可以为查询定义自己的区域

例如,设置"分析"缓存区域

@Repository
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class AnalyticsRepositoryImpl implements AnalyticsRepository {
public Map<Long, Long> getAgeStatistic(boolean onlyPaid) {
StringBuilder sb = new StringBuilder();
sb.append("SELECT (date_part('year',current_date) - date_part('year',a.date_value))  as age, COUNT(u.id) as count from answers a ");
sb.append("JOIN ...");
...
Query q = em.createNativeQuery(sb.toString());
// enable the cache for the native query
NativeQuery nativeQuery = q.unwrap(NativeQuery.class);
nativeQuery.addScalar("age", IntegerType.INSTANCE);
nativeQuery.addScalar("count", LongType.INSTANCE);
nativeQuery.setCacheable(true);
nativeQuery.setCacheRegion("analytics");
List<Object[]> result = q.getResultList();
// Place results in map
Map<Long, Long> map = convertResultSetToLongKeyMap(result);
return map;
}

并在 EHCACHE 配置中

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxEntriesLocalHeap="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxEntriesLocalDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
<cache name="analytics"
maxEntriesLocalHeap="10000"
eternal="false"
timeToIdleSeconds="6000"
timeToLiveSeconds="6000">
<persistence strategy="localTempSwap"/>
</cache>
</ehcache>