问题来源:
雪花算法生成的是19位id,并且是Long类型,64bit,这在服务端上使用long类型是可以的.但是当把id从后端传给js(js使用number接收,number的精度是16位),这时候会出现精度的丢失.
结局方法:
雪花算法生成的id,服务端响应页面时,json处理,将id转化为String.
代码(/架构):扩展mvc架构的消息转换器
public class JacksonObjectMapper extends ObjectMapper {
public static final String Default_Date_FORMAT = "yyyy-MM-dd";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
public JacksonObjectMapper() {
super();
//收到未知属性时不报异常
this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//反序列化时,属性不存在的兼容处理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule simpleModule = new SimpleModule()
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(Default_Date_FORMAT)))
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(BigInteger.class, ToStringSerializer.instance)
//重点在这里Long序列化,使用的是ToStringSerizlizer;
.addSerializer(Long.class, ToStringSerializer.instance)
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(Default_Date_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
this.registerModule(simpleModule);
}
}
为什么雪花算法能生成分布式系统唯一id:
对于不同设备,机器id会不同..对于同一设备,有41位来记录时间戳到毫秒级别,同一毫秒级别,12位来记录(自增).
mybatis-plus默认的主键生成策略就是雪花算法,并且还提供了一个工具类(IdWorker)来供开发者使用.
System.out.println(IdWorker.getId());