java中应绕过java原生序列化,用jackson将bigdecimal转为标准json数字存入redis;因jdkserializationredisserializer产生不可读二进制且跨语言不兼容,而jackson启用write_bigdecimal_as_plain后可精准输出99.95而非科学计数法,支持跨语言与调试。

Java中把 BigDecimal 以 JSON 格式 存入 Redis,核心不是让它实现 Serializable,而是**绕过 Java 原生序列化**,改用 JSON 序列化器(如 Jackson)统一处理所有对象——包括 BigDecimal。因为 BigDecimal 本身不实现 Serializable 并不影响 JSON 序列化,它天然支持转成字符串(如 "123.45"),而 JSON 序列化器会自动处理这种转换。
为什么不能依赖 Serializable 存 BigDecimal 到 Redis
Redis 默认的 RedisTemplate 若未配置序列化器,会使用 JdkSerializationRedisSerializer,要求对象必须实现 Serializable,且序列化结果是二进制、不可读、跨语言不兼容。BigDecimal 虽实现了 Serializable,但这样存进去的数据:
- 在 Redis CLI 或可视化工具里看到的是乱码字节,无法直观查看数值
- 其他服务(如 Node.js、Python)无法解析该二进制流
- 精度虽保留,但调试、监控、人工干预成本高
正确做法:用 Jackson + StringRedisTemplate 或自定义 JSON RedisTemplate
推荐使用 StringRedisTemplate(键值均为 String),或为 RedisTemplate<string object></string> 配置 Jackson 序列化器。关键点在于让 BigDecimal 被 Jackson 正确序列化为标准 JSON 数字(非字符串),同时避免科学计数法、保留精度。
- 确保 Jackson 的
ObjectMapper启用WRITE_BIGDECIMAL_AS_PLAIN(防止1E+8类型输出) - 禁用
WRITE_DATES_AS_TIMESTAMPS(虽不直接相关,但常配套设置) - 不需额外写 BigDecimalSerializer —— Jackson 2.12+ 对 BigDecimal 有开箱即用的精准支持
配置示例(Spring Boot + Jackson2JsonRedisSerializer)
在配置类中定义带 Jackson 序列化器的 RedisTemplate:
Object.class,Jackson 会自动处理 BigDecimal、LocalDateTime、List 等)
@Bean
public RedisTemplate<string object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<string object> template = new RedisTemplate();
template.setConnectionFactory(factory);
// 键统一用 String 序列化
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
// 值用 Jackson 序列化为 JSON 字符串
Jackson2JsonRedisSerializer<object> serializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.enable(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN); // ✅ 关键:避免 1.23E+5
serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}</object></string></string>
存取 BigDecimal 的实际写法
使用时无需特殊处理,直接塞进 Map 或对象里即可:
- 存:
redisTemplate.opsForValue().set("order:1001", new Order("A001", new BigDecimal("99.95"))); - 取:
Order order = redisTemplate.opsForValue().get("order:1001");→ BigDecimal 字段自动还原,精度无损
Redis 中存储的是标准 JSON 字符串,例如:{"id":"A001","amount":99.95},可读、可调试、跨语言通用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











