使用的是Spring的RedisTemplate
存储为Redis的Hash类型
取值时控制台输出
存Redis时是Map<Integer, Object>类型,key是Integer
从Reids取时,key转为了String类型
所以又用String类型的key来取
控制台可以正确输出
很明显是Redis序列化问题
public class RedisConfiguration {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 开启事务
redisTemplate.setEnableTransactionSupport(true);
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer =
new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
RedisSerializer<?> redisSerializer = new StringRedisSerializer();
// key
redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
// value
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
可以看到,HashValue使用的是Jackson的序列化,Jackson默认会将Map的Integer转为String,所以出现最开始的取不到值的情况.
若想在序列化时保持原类型,可以使用JdkSerializationRedisSerializer进行序列化.(注意,使用JDK序列化,序列化对象需实现Serializable接口)
Jackson序列化后在redis中的格式
JDK序列化后在Redis的格式
很明显,Jackson序列化后的byte比Jdk序列化后的占用空间小很多.所以大多数情况使用的都是Jackson序列化.
若是遇到如上情况,尽量将Map中的key设为String,获取在取值时封装工具类将key转String.
一次脑残的踩坑,仅此记录