原文网址:SpringBoot--解决雪花算法主键ID传到前端后精度丢失问题_IT利刃出鞘的博客-CSDN博客
简介
本文用示例介绍SpringBoot如何解决雪花算法主键ID传到前端后精度丢失问题。
问题描述
Java后端Long类型的范围
- -2^63~2^63,即:-9223372036854775808~9223372036854775807,它是19位的。
- 这个数字可以通过方法获得:Long.MAX_VALUE、Long_MIN_VALUE。
前端JS的数字类型的范围
- -2^53~2^53,即:-9007199254740991~9007199254740991,它是16位的。
- 这个数字可以通过方法获得:Number.MAX_SAFE_INTEGER、Number.MIN_SAFE_INTEGER。
结论
可见,Java后端的Long宽度大于前端的。雪花算法一般会生成18位或者19位宽度的数字,那么这时就会出问题。
项目场景
1.表结构
主键类型是BIGINT,存储雪花算法生成的ID。
CREATE TABLE `user` (
`id` BIGINT(32) NOT NULL COMMENT '用户id',
...
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
2.Entity
用Long 类型对应数据库ID的BIGINT类型。
这里使用 MybatisPlus 的雪花算法自动生成19位长度的纯数字作为主键ID。(当然也可以手动用雪花算法生成ID)
import lombok.Data;
@Data
public class User {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
//其他成员
}
3.响应给前端
以JSON数据响应给前端正常
{
"id": 1352166380631257089,
...
}
问题描述
实例
Controller
package com.knife.example.business.product.controller;
import com.knife.example.business.product.vo.ProductVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
@Api(tags = "商品")
@RestController
@RequestMapping("product")
public class ProductController {
@ApiOperation("查询")
@GetMapping("query")
public ProductVO query(Long id) {
//省略查数据库等逻辑。
//为了简便,直接虚构一个vo
ProductVO productVO = new ProductVO();
productVO.setId(id);
productVO.setName("鼠标");
return productVO;
}
}
VO
package com.knife.example.business.product.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@ApiModel("商品响应类")
public class ProductVO {
@ApiModelProperty("id")
private Long id;
@ApiModelProperty("名字")
private String name;
}
测试
访问:http://localhost:8080/product/query?id=1352213368413982722
结果
问题复现
从上边可以看到,并没有问题。
为什么没有出问题?
- 前端传入后端:SpingMVC会自动将String类型的ID转为Long类型,不会出问题
- 后端响应给前端:是JSON格式,与JS没有关系,不会出问题
什么时候会出问题?
前端接收到JSON之后,将其序列化为JS对象,然后进行其他操作。在JSON转JS对象时就会出问题,如下:
可以看到,原来id为1352213368413982722,序列化为JS对象后变成了 1352213368413982700
代码为:
const json = '{"id": 1352213368413982722, "name": "鼠标"}';
const obj = JSON.parse(json);
console.log(obj.id);
console.log(obj.name);
解决方案
上边是本文的部分内容,为便于维护,全文已转移到此网址:SpringBoot-解决雪花算法主键ID传到前端后精度丢失问题 - 自学精灵