在redis中我们有时候需要清除掉指定前缀的数据。但是在spring的redis注解默认配置使用上好像并没有清除指定前缀的数据,如下我们来举例如何使用@CacheEvict清除指定前缀的数据。
@CacheEvict(value = "default",
key = "'Resources*'",
unless = "#result == false ")
@Override
public Boolean deleteByPrimaryKey(String id){}
当前操作是删除Resources为前缀的所有redis数据。但是执行是失败的,失败的原因是没有这个key。
很明显,注解并没有将这个key当作一个前缀来处理而是当作了一个key来处理,所以导致的就是无法找到这个key。
所以我们要做的就是,修改注解解析,在解析注解的时候使他默认识别这个前缀。
1> 第一种方法 修改配置
我们在配置redis缓冲管理器的时候会配置一个RedisCacheWriter,我们默认使用的实现类是org.springframework.data.redis.cache.DefaultRedisCacheWriter,而这个删除注解执行的时候会执行这个类里面的remove方法,所以们只需要对这个remove方法进行修改就可以了(重写这个类,并重新进行实例化)。
修改前
/*
* (non-Javadoc)
* @see org.springframework.data.redis.cache.RedisCacheWriter#remove(java.lang.String, byte[])
*/
@Override
public void remove(String name, byte[] key) {
Assert.notNull(name, "Name must not be null!");
Assert.notNull(key, "Key must not be null!");
execute(name, connection -> connection.del(key));
}
修改后
/*
* (non-Javadoc)
* @see org.springframework.data.redis.cache.RedisCacheWriter#remove(java.lang.String, byte[])
*/
/**
* Description :删除,原来是删除指定的键,目前修改为既可以删除指定键的数据,也是可以删除某个前缀开始的所有数据
* @param
* @return
* @exception
* @author :loulan
* */
@Override
public void remove(String name, byte[] key) {
Assert.notNull(name, "Name must not be null!");
Assert.notNull(key, "Key must not be null!");
execute(name, connection -> {
// 获取某个前缀所拥有的所有的键,某个前缀开头,后面肯定是*
Set<byte[]> keys = connection.keys(key);
int delNum = 0;
for (byte[] keyByte : keys) {
delNum += connection.del(keyByte);
}
return delNum;
});
}
如果key里面带有*,那么就会被keys去查询以其前缀为值得所有key,然后再把这些key得数据全部进行删除。这样原来得注解方式不用改动就可以生效了。
2> 第二种方法,修改属性cacheResolver,自定义解析程序
这种方式有些麻烦,自己也没有进行测试,有做过得请分享一下。
注 注解得使用