StringRedisTemplate与RedisTemplate区别

1,200 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情

引入依赖注入

maven依赖包spring-boot-starter-data-redis, 然后在service中注入StringRedisTemplate或者RedisTemplate即可:

@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RedisTemplate redisTemplate;

StringRedisTemplate与RedisTemplate区别:

• 两者的关系是StringRedisTemplate继承RedisTemplate。

• 两者的数据是不共通的;

    StringRedisTemplate只能管理StringRedisTemplate里面的数据。
    RedisTemplate只能管理RedisTemplate中的数据。
    

• 其实他们两者之间的区别主要在于他们使用的序列化类:

    RedisTemplate使用的是JdkSerializationRedisSerializer  存入数据会将数据先序列化成字节数组然后在存入
    Redis数据库。 
    StringRedisTemplate使用的是StringRedisSerializer

• 使用时注意事项

    当你的redis数据库里面本来存的是字符串数据或者你要存取的数据就是字符串类型数据的时候,
    那么你就使用StringRedisTemplate即可。
    
    但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,
    那么使用RedisTemplate是更好的选择。
    

• RedisTemplate使用时常见问题

    redisTemplate 中存取数据都是字节数组。当redis中存入的数据是可读形式而非字节数组时,
    使用redisTemplate取值的时候会无法获取导出数据,获得的值为null。
    可以使用 StringRedisTemplate 试试。
    

• RedisTemplate中定义了5种数据结构操作:

    redisTemplate.opsForValue();  //操作字符串
    redisTemplate.opsForHash();   //操作hash
    redisTemplate.opsForList();   //操作list
    redisTemplate.opsForSet();    //操作set
    redisTemplate.opsForZSet();   //操作有序set
    

• RedisTemplate可以定义操作泛型

public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
   RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
   redisTemplate.setConnectionFactory(factory);
   return redisTemplate;
}
public RedisTemplate<String, Serializable> limitRedisTemplate(LettuceConnectionFactory redisConnectionFactory) {
    RedisTemplate<String, Serializable> template = new RedisTemplate<String, Serializable>();
    template.setKeySerializer(new StringRedisSerializer());
    template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}
public RedisTemplate<String, Object> redisObjectTemplate(RedisConnectionFactory factory) {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
    redisTemplate.setConnectionFactory(factory);

    RedisSerializer<String> redisSerializer = new
            StringRedisSerializer();
    redisTemplate.setKeySerializer(redisSerializer);
    redisTemplate.setHashKeySerializer(redisSerializer);

    return redisTemplate;
}

• RedisTemplate反序列化increment()方法错误

redis反序列化当调用increment方法自增long类型数据时,异常报错: RedisCommandExecutionException: ERR hash value is not an integer

原因分析:

GenericJackson2JsonRedisSerializer、Jackson2JsonRedisSerializer是先将对象转为json,然后再保存到redis,所以,1在redis中是字符串1,所以无法进行加1。

JdkSerializationRedisSerializer使用的jdk对象序列化,序列化后的值有类信息、版本号等,所以是一个包含很多字母的字符串,所以根本无法加1。

GenericToStringSerializer、StringRedisSerializer将字符串的值直接转为字节数组,所以保存到redis中是数字,所以可以进行加1 ;通过以下代码配置redistemplate的序列化方式之后就可以顺利的执行increment了。

@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    
    template.setConnectionFactory(redisConnectionFactory);
    // 创建 序列化类
    //解决redis的Long的increment自增报错
    GenericToStringSerializer genericToStringSerializer = new GenericToStringSerializer(Object.class);

    // 7.设置 value 的转化格式和 key 的转化格式
    template.setValueSerializer(genericToStringSerializer);
    template.setKeySerializer(new StringRedisSerializer());
    template.afterPropertiesSet();
    return template;
    }
}