解决redis的key和value出现乱码(更准确的说是二进制形式)

问题描述

redis执行代码时key和value会以乱码(二进制形式)存储,更准确的说不是乱码,只是redis以二进制的方式存储,这种方式不方便用可视化的redis管理工具查看,所以我们需要将它序列化


原因分析:

这是因为在redis储存的时候没有对key和value进行序列化,默认情况下的模板RedisTemplate,默认序列化使用的是 JdkSerializationRedisSerializer ,存储二进制字节码。这时需要自定义模板。


解决方案:

1、自定义RedisTemplate模板(redis的key需序列化,value可以不序列化)

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory){
        RedisTemplate redisTemplate = new RedisTemplate<>();
        //设置String类型的key设置序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //设置Hash类型的key设置序列化器
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        //设置redis链接Lettuce工厂
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        return redisTemplate;
    }
}

当然也可以对value进行序列化,至于为什么不对value序列化等下再作出解释

2、注入模板,执行代码

@Autowired
private RedisTemplate redisTemplate;
@Test
void test(){
    ValueOperations ops = redisTemplate.opsForValue();
    ops.set("name","YHJ");
}

3、结果如下

Value还是以二进制的形式存进去,这是因为我们没有对value进行序列化,虽然value的格式有点难看,但是这样也可以正常取出来,因为在java代码取value值的时候,还会进行反序列化,不会影响业务的逻辑和数据的正确性,结果如下:

 4、我们为什么不对value进行序列化呢

这是因为redis的value最好不要设置String序列化,若设置序列化了,value只能存入String类型,不能存进LocalDateTime、LocalDate、LocalTime等时间类型(若想存这些类型也是可以的,需要将这些数据强转为string类型再存进value里即可),通常开发中我们是不需要查看value的,只需要查看key。

若想value也序列化的话就是用这配置,但是记得若将值存进value的话最好还是要保证要存进去的值是String类型

/**
 * Redis配置类,设置序列化
 */
@Configuration
public class RedisConfig {
    /**
     * 设置序列化
     *
     * @return
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate<>();
        // String类型 key序列器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // String类型 value序列器
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        // Hash类型 key序列器
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        // Hash类型 value序列器
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        // 把连接工厂放进去
        redisTemplate.setConnectionFactory(connectionFactory);
        return redisTemplate;
    }
}