long类型64位,JS的Number精度只有53位,所以后台数据传到前端的时候,精度丢失,后面几位被置为0了。
尝试过的解决办法:
1、在Long类型字段上使用注解标明序列化方式。此方式细粒度到当前字段,我尝试了几种方法之后选用了此方法。
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
2、自定义解析方法
/**
* 解决Jackson导致Long型数据精度丢失问题
*
* @return
*/
@Bean("jackson2ObjectMapperBuilderCustomizer")
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
Jackson2ObjectMapperBuilderCustomizer customizer =
jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder
.serializerByType(Long.class, ToStringSerializer.instance)
.serializerByType(Long.TYPE, ToStringSerializer.instance);
return customizer;
}
3、自定义ObjectMapper,没找到代码就不写了。
4、自定义MappingJackson2HttpMessageConverter,此方法可以指定拦截哪些请求(其他方法应该也可以实现)才做处理。
当然还有其他方法自行百度吧。
其中,后面几种方法是把返回的实体中所有的long类型都转成了字符串类型,项目中应该根据实际需要,选取合适的方案。
背景:
最近工作中,被运维要求整改mysql数据库表,大体分两类:无主键 和 使用了自增ID。
无主键的表,就加个主键呗,还能提升查询效率,一句sql搞定。
使用自增ID的表,就把自增去掉呗,然后根据业务需要,大概找了一些分布式ID生成方案做参考,选用了美团的leaf中snowflake的实现(其他方案可以自行百度),源码见链接 https://github.com/Meituan-Dianping/Leaf 。
简单聊一下,long类型一共64位,去掉一个符号位,10位workID,12位自增序列,还有41位取时间戳差值,简单算一下可以使用69年(估计我不在了,程序还在)。这样一算,10位workID最多支持1024个节点(一台机器上的一个服务对应一个节点)同时注册(目前我们所有节点加一起应该不超过50个),workID使用ZK的顺序节点实现,12位自增序列每ms就有4000个左右(每秒就可以生成400W个ID),这样完全满足我们业务使用了。
后端改好了美滋滋,打包,上环境,完了,各种报错。