我有一个如下所示的服务方法,它使用grails.gorm.DetachedCriteria
作为参数。由于经常调用此方法,我想缓存此方法。但在这种情况下,每次调用该方法时,我都会遇到db。我使用grails“Cache plugin”
@Cacheable("totalCountCache")
public int count(DetachedCriteria detachedCriteria) throws Exception {
return detachedCriteria.count();
}
答案 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(),因为它在这里被用作关键。