一、问题描述
数据库:
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
......
);
java实体类:
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("user")
public class User {
@ApiModelProperty(value = "用户Id")
@TableId(value = "id")
private Long id;
......
}
项目使用MyBatis-Plus,默认的主键策略是:ASSIGN_ID (使用了雪花算法)
测试调试的时候后端打印出id字段与数据库保证一致,但是前端获取到id后导致精度丢失
二、解决问题
解决思路:后端的ID(Long) ==> Jackson(Long转String) ==> 前端使用String类型的ID,前端使用js string精度就不会丢失了。 那前端再把String类型的19位数字传回服务端的时候,可以用Long接收么?当然可以,这是Spring反序列化参数接收默认支持的行为。
最终方案就是:前端用String类型的雪花ID保持精度,后端及数据库继续使用Long(BigINT)类型不影响数据库查询执行效率。
剩下的问题就是:在Spring Boot应用中,使用Jackson进行JSON序列化的时候怎么将Long类型ID转成String响应给前端。方案如下:
@Configuration
public class JacksonConfig {
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder)
{
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
// 全局配置序列化返回 JSON 处理
SimpleModule simpleModule = new SimpleModule();
//JSON Long ==> String
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
return objectMapper;
}
}
到此问题解决