Grails - 如何使用grails.gorm.DetachedCriteria作为参数来缓存服务方法?

时间:2013-06-12 05:00:54

标签: caching grails service

我有一个如下所示的服务方法,它使用grails.gorm.DetachedCriteria作为参数。由于经常调用此方法,我想缓存此方法。但在这种情况下,每次调用该方法时,我都会遇到db。我使用grails“Cache plugin”

@Cacheable("totalCountCache")
public int count(DetachedCriteria detachedCriteria) throws Exception {
    return detachedCriteria.count();
}

2 个答案:

答案 0 :(得分:0)

如果您未指定密钥,则将使用以下默认密钥生成策略:

public Object generate(Object target, Method method, Object… params) {

   if (params.length == 1) {
      return (params[0] == null ? 53 : params[0]);
   }

   if (params.length == 0) { return 0; }

   int hashCode = 17; 

   for (Object object : params) { 
      hashCode = 31 * hashCode + (object == null ? 53 : object.hashCode()); 
   } 
   return hashCode; 
} 

由于您的方法只有一个参数,detachedCriteria本身将用作密钥,因此如果出现以下情况,将丢失缓存:

  • 您使用唯一的detachedCriteria对象(以前未曾遇到的对象)
  • 来调用此方法
  • 您使用之前遇到的detachedCriteria调用此方法,但此对象的缓存值已过期

如果此密钥生成策略不合适,您可以通过定义实现webCacheKeyGenerator接口的名为grails.plugin.cache.web.filter.WebKeyGenerator的spring bean来覆盖它(您可以继承DefaultWebKeyGenerator以简化实现此接口)。

答案 1 :(得分:0)

这个问题的焦点应该是函数参数DetachedCriteria。 (据我所知),DetachedCriteria无法用作密钥。

幸运的是,我有另一个对象'UserCriteria'(这是我创建的自定义对象),用于创建DetachedCriteria。所以我更新了方法,以便它接受我的'UserCriteria'对象作为参数。如下所示

@Cacheable(value='userTotalCountCache', key='#userCriteria.toString()')
public int count(UserCriteria userCriteria) throws Exception {
    DetachedCriteria detachedCriteria = getDetachedCriteria(userCriteria);
    return detachedCriteria.count();
}

它有效。

PS:为了实现这一点,我必须覆盖UserCriteria的toString(),因为它在这里被用作关键。