精度long类型的d订单id传到前端会造成精度丢失?
本文插图
最近公司的一个项目组要把以前的单体应用进行为服务拆分 , 表的ID主键使用Mybatis plus默认 的雪花算法来生成 。
快下班的时候 , 小伙伴跑过来找我 , :“快给我看看这问题 , 卡这卡了小半天了!” 。 连拉带拽 , 连哄带骗的把我拉到他的电脑前面 。 这位小伙伴在我看来技术不算是大牛 , 但经验也很丰富了 。 他都卡了半天的问题 , 应该不是小问题 , 如果我一时半会搞不定 , 真的是耽误我下班了 , 所以我很不情愿的在他的位置坐了下来 。
一、现象是这样的 下面我把异常的现象给大家描述一下 , 小伙伴建了一张表 , 表的主键是id BigINT , 用来存储雪花算法生成的ID , 嗯 , 这个没有问题!
CREATE TABLE user( id BIGINT(20) NOT NULL COMMENT "主键ID", #其他字段省略)
使用Long 类型对应数据库ID数据 。 嗯 , 也没有问题 , 雪花算法生成的就是一串数字 , Long类型属于标准答案!
@Datapublic class User { private Long id//其他成员变量省略
在后端下断点 。 看到数据响应以JSON响应给前端 , 正常
{id:1297873308628307970,//其他属性省略}
最后 , 这条数据返回给前端 , 前端接收到之后 , 修改这条数据 , 后端再次接收回来 。 奇怪的问题出现了:后端重新接收回来的id变成了:12978733086283000000 , 不再是1297873308628307970
二、分析问题 我的第一感觉是 , 开发小伙伴把数据给搞混了 , 张冠李戴了 , 把XXX的对象ID放到了YYY对象的ID上 。 所以 , 就按照代码从前端到后端、从后端到前端调试跟踪了一遍 。
从代码的逻辑角度上没有任何问题 。 这时 , 我有点烦躁了 , 真的是耽误我下班了!但开工没有回头箭 , 既然坐下来了就得帮他解决 , 不然以后这队伍怎么带?想到这我又静下心来 , 开始思考 。
1297873308628300000 ---> 1297873308628307970复制代码
这两个数长得还挺像的 , 似乎是被四舍五入了 。 此时脑袋里面冒出一个想法 , 是精度丢失了么?哪里能导致精度丢失?
- 服务端都是Long类型的id , 不可能丢失
- 前端是什么类型 , JSON字符串转js对象 , 接收Long类型的是number
三、解决问题
开发小伙伴说:那我把所有的数据库表设计 , id字段由Long类型改成String类型吧 。 我问他你有多少张表?他说100多张吧 。
- 100多张表还有100多个实体类需要改
- 还有各种使用到实体类的Service层要改
- Service等改完Controller层要改
- 关键的是String和Long都是常用类型 , 他还不敢批量替换
解决思路:后端的ID(Long) ==> Jackson(Long转String) ==> 前端使用String类型的ID,前端使用js string精度就不会丢失了 。那前端再把String类型的19位数字传回服务端的时候 , 可以用Long接收么?当然可以 , 这是Spring反序列化参数接收默认支持的行为 。
- 「猫奴」科学研究发现“猫奴”分为5种类型
- 车驰夜幕|美国GPS卫星精度0.4米,俄卫星的精度1.2米,中国北斗呢?
- 3DM游戏网|《辐射:新维加斯》高清材质MOD发布 大幅提高精度
- 科学研究发现“猫奴”分为5种类型
- 契约法|经典之经典:王轶《合同法的规范类型》讲座听课笔记及视频
- 津爱改装车|来,全搞懂,原来Mybatis执行一个sql有这么多类型,绝
- 皮肤疾病|想除斑先搞懂你是哪种斑!皮肤科医师教6大类型斑点判别法
- 绝地求生小饭堂|PCS2洲际赛iFTY依然是第一!LongSkr数据太恐怖
- 中国新闻周刊|高考作文20年:命题类型变化敌不过套路长存
- 淡蓝色的记忆|张予曦“撞脸”陈瑶?同为偏瘦甜美类型,这两大美女你更喜欢谁?