Redis库使用的是spring-boot-data-redis,Redis的Hash结构存储Long数字类型,但取出来的是Integer,不用Hash直接存,取的就是Long,这是为什么?有办法Hash取的也是Long吗
直接存:
存到hash中:
存储hash的代码:
private void setArticleActiveHash(Long articleId) {
String key = "article_active:"+ articleId;
Map<String, Long> articleActiveMap = new HashMap<>();
articleActiveMap.put("love", 0L);
articleActiveMap.put("commentCount", 0L);
articleActiveMap.put("watch", 0L);
articleActiveMap.put("collectionCount", 0L);
articleActiveMap.put("articleId",articleId);
redisCache.setCacheMap(key,articleActiveMap);
}
RedisConfig
@Configuration
public class RedisConfig {
@Resource(type = RedisConnectionFactory.class)
private RedisConnectionFactory redisConnectionFactory;
@Primary
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
// 解决反序列化 LocalDateTime 的错误
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// 解决 LocalDateTime 序列化失败的问题
objectMapper.registerModule(new JavaTimeModule());
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.activateDefaultTyping(
LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.WRAPPER_ARRAY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key 采用 String 的序列化方式
template.setKeySerializer(stringRedisSerializer);
// value 序列化方式采用 jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash 的 key 也采用 String 的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// hash 的 value 序列化方式采用 jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
虽然可以拿到后转Long,但每次都转好麻烦
这是jackson一直存在的一个问题,虽然现在被解决了,但是低版本的jackson仍然存在问题,问题存在于
ObjectMapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
不论
DefaultTyping
选择什么,Long
类型序列化,都是不携带typing
的。高版本新增了
DefaultTyping.EVERYTHING
来解决,但是低版本可以参考redisson
的解决方案,位于org.redisson.codec.JsonJacksonCodec#initTypeInclusion
重点在
Redisson
解决非常完美,可以参考,我在两年前做架构师时,将该方案已经用到了生产上。