RedisTemplate和StringRedisTemplate的区别

StringRedisTemplate是继承RedisTemplate,但是两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。

序列化策略两者也不同

  • StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。
  • RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。

RedisTemplate使用的序列类在在操作数据的时候,比如说存入数据会将数据先序列化成字节数组然后在存入Redis数据库,这个时候打开Redis查看的时候,

你会看到你的数据不是以可读的形式展现的,而是以字节数组显示,类似下面

在这里插入图片描述

当然从Redis获取数据的时候也会默认将数据当做字节数组转化,这样就会导致一个问题,当需要获取的数据不是以字节数组存在redis当中时,而是正常的可读的普通字符串的时候,RedisTemplate就无法获取导数据,这个时候获取到的值就是NULL。这个时候StringRedisTempate就派上了用场。

所以当你使用RedisTemplate获取不到数据的时候请检查一下是不是Redis里面的数据是可读形式而非字节数组.

综上
当你的redis数据库里面本来存的是字符串数据或者你要存取的数据就是字符串类型数据的时候,那么你就使用StringRedisTemplate即可,

但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,那么使用RedisTemplate是更好的选择。

keys在扫描大key的时候会阻塞redis进程,可以使用scan分批获取

要注意使用redistemplate的scan操作不支持redis集群


//要指定类型,不然下面del删除操作不会成功,不指定泛型操作的不是字面上的key
@Autowired
private RedisTemplate<String,String> redisTemplate;

private Set<String> scanTargetKeys(String keyWords){
    return redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
        Set<String> keysTmp = new HashSet<>();
        Cursor<byte[]> cursor = connection.scan(
               new ScanOptions.ScanOptionsBuilder().match(
                       keyWords + "*"
               ).count(scanCount).build()
        );

        while (cursor.hasNext()){
            keysTmp.add(new String(cursor.next()));
        }

        return keysTmp;
    });
}
.
.
.
//调用上面的方法
Set<String> keys = scanTargetKeys(cacheName);
if(!ObjectUtils.isEmpty(keys)){
    redisTemplate.delete(keys);
}

RedisTemplate没有指定泛型默认使用jdk序列化策略,会有前缀
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐