雪花算法生成的ID精度丢失问题

引入雪花算法当作生成主键,遇到问题如下:
前端请求获取的response的值,ID和后端返回的值不一致,排查了很久发现是前端在获取时将Long类型值转换超范围导致丢失精度

Java后端Long类型的范围

  • -263~263,即:-9223372036854775808~9223372036854775807,它是19位的。
    • 这个数字可以通过方法获得:Long.MAX_VALUE、Long_MIN_VALUE。

前端JS的数字类型的范围

  • -253~253,即:-9007199254740991~9007199254740991,它是16位的。
    • 这个数字可以通过方法获得:Number.MAX_SAFE_INTEGER、Number.MIN_SAFE_INTEGER。

解决办法

  1. 全局处理自定义ObjectMapper
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
 
@Configuration
public class JacksonConfig {
    
    
 
    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
    
    
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
 
        // 全局配置序列化返回 JSON 处理
        SimpleModule simpleModule = new SimpleModule();
        // 将使用String来序列化Long类型
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        return objectMapper;
    }
}
  1. 局部处理:
    在字段上加:@JsonSerialize(using= ToStringSerializer.class)
@Id
@GeneratedValue(generator = "myIDGenerator")
@JsonSerialize(using= ToStringSerializer.class)
private Long id;

注意:全局处理会将分页参数页码、总条数值也转成string类型

  1. 在application.yml中加上以下配置,这个办法会将所有数字都变成字符串,包括long和int类型
spring:
  jackson:
    generator:
      writeNumbersAsStrings: true
  1. 如果想要前端不丢失精度,JSON中的id就不能是long类型,改为String类型就好了。
    这个方案如果此id用的类少,就可以改id的数据类型,但是当用到的类多的话要改过来就需要花很长时间,并且不能保证都能改过来,而且不会出问题。

猜你喜欢

转载自blog.csdn.net/qq_45924975/article/details/128903215