记一次Redis批量删除Key问题

记一次Redis批量删除Key问题

前言

最近在项目中使用redis时发现一个问题,批量删除的时候删除不了。

代码如下

// redis配置
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
    RedisTemplate redisTemplate = new RedisTemplate();
    redisTemplate.setConnectionFactory(factory);
    return redisTemplate;
}

// 批量获取key
@Override
public Set<String> getKeys(String keyPattern) {
    return redisTemplate.keys(keyPattern);
}
// 批量删除key
@Override
public void delKeys(Set<String> keys) {
    redisTemplate.delete(keys);
}
@Test
public void testDeleteKeys() {
    String key="test";
    for (int i = 0; i < 5; i++) {
        redisObjectService.set(key + i, i);
    }
    Set<String> keys = redisService.getKeys(key + "*");
    redisObjectService.delKeys(keys);
    for (int i = 0; i < 5; i++) {
        Object o = redisService.get(key + i);
        System.out.println(o);
    }

}

//输出
0
1
2
3
4

由输出结果可以看出之前存储的键值对并没有删除。

问题原因

经过一番查找得出,redisTemplate自带的序列化方式是JdkSerializationRedisSerializer

在这里插入图片描述

而这个序列化方式生成的key会自带一串乱码前缀,如下图所示

在这里插入图片描述

而这也正是导致批量删除失败的原因。因为这一串前缀导致匹配不上,故删除不了。

解决方法

知道了问题就很好解决了,只需要换一种redis序列化 方式,换成StringRedisSerializer即可。

redis配置改成如下即可解决问题。

@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
    RedisTemplate redisTemplate = new RedisTemplate();
    redisTemplate.setConnectionFactory(factory);
    StringRedisSerializer serializer = new StringRedisSerializer();
    redisTemplate.setKeySerializer(serializer);
    return redisTemplate;
}

但是改完之后,又出现了另一个问题,由于这是一个springboot项目,spring boot中有集成redis缓存。

在使用@cacheable时如果不指定key,springboot会选择默认的SimpleKey类型作为默认的Key,源码如下图:
CacheAspectSupport.java

这就会引发一个类型转换的错误:
org.springframework.cache.interceptor.SimpleKey cannot be cast to java.lang.String
图我就不放了,这时的解决办法是重写keyGenerator方法

如下代码:

@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
    RedisTemplate redisTemplate = new RedisTemplate();
    redisTemplate.setConnectionFactory(factory);
    StringRedisSerializer serializer = new StringRedisSerializer();
    redisTemplate.setKeySerializer(serializer);
    return redisTemplate;
}

@Override
@Bean
public KeyGenerator keyGenerator() {
    return (target, method, params) -> {
        StringBuilder sb = new StringBuilder();
        sb.append(target.getClass().getName());
        sb.append(method.getName());
        for (Object obj : params) {
            sb.append(obj.toString());
        }
        return sb.toString();
    };
}

到这里,问题才算完整解决了。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值