1

我有一个如下所示的服务方法,它grails.gorm.DetachedCriteria用作它的参数。由于此方法被频繁调用,因此我想缓存此方法。但在这种情况下,每次调用该方法时,我都会对 db 产生影响。我使用 grails“缓存插件”

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

2 回答 2

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对象(以前没有遇到过的对象)调用这个方法
  • 您使用之前遇到过的 a 调用此方法detachedCriteria,但为此对象缓存的值已过期

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

于 2013-06-12T13:57:23.127 回答
0

这个问题的重点应该是函数的参数,DetachedCriteria。(据我所知)没有办法将 aDetachedCriteria用作钥匙。

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

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

它奏效了。

PS:为此,我必须覆盖 toString() 的UserCriteria,因为它在这里用作键。

于 2013-06-17T08:43:57.113 回答