最近公司的一个项目组要把以前的单体应用进行为服务拆分,表的ID主键使用Mybatis plus默认 的雪花算法来生成。

快下班的时候,小伙伴跑过来找我,:“快给我看看这问题,卡这卡了小半天了!”。连拉带拽,连哄带骗的把我拉到他的电脑前面。这位小伙伴在我看来技术不算是大牛,但经验也很丰富了。他都卡了半天的问题,应该不是小问题,如果我一时半会搞不定,真的是耽误我下班了,所以我很不情愿的在他的位置坐了下来。

## 一、现象是这样的

下面我把异常的现象给大家描述一下,小伙伴建了一张表,表的主键是id BigINT,用来存储雪花算法生成的ID,嗯,这个没有问题!

~~~

CREATE TABLE user

(

id BIGINT(20) NOT NULL COMMENT '主键ID',

#其他字段省略

);

~~~

使用Long 类型对应数据库ID数据。嗯,也没有问题,雪花算法生成的就是一串数字,Long类型属于标准答案!

~~~

@Data

public class User {

private Long id;

//其他成员变量省略

~~~

在后端下断点。看到数据响应以JSON响应给前端,正常

~~~

{

id:1297873308628307970,

//其他属性省略

}

~~~

最后,这条数据返回给前端,前端接收到之后,修改这条数据,后端再次接收回来。奇怪的问题出现了:**后端重新接收回来的id变成了:12978733086283000000,不再是1297873308628307970**

## 二、分析问题

我的第一感觉是,开发小伙伴把数据给搞混了,张冠李戴了,把XXX的对象ID放到了YYY对象的ID上。所以,就按照代码从前端到后端、从后端到前端调试跟踪了一遍。

从代码的逻辑角度上没有任何问题。这时,我有点烦躁了,真的是耽误我下班了!但开工没有回头箭,既然坐下来了就得帮他解决,不然以后这队伍怎么带?想到这我又静下心来,开始思考。

~~~

1297873308628300000 ---> 1297873308628307970

~~~

这两个数长得还挺像的,似乎是被四舍五入了。此时脑袋里面冒出一个想法,是精度丢失了么?哪里能导致精度丢失?

* 服务端都是Long类型的id,不可能丢失

* 前端是什么类型,JSON字符串转js对象,接收Long类型的是number

上网查了一下Number精度是16位(雪花ID是19位的),So:JS的Number数据类型导致的精度丢失。问题是找到了!

小伙伴投来敬佩的眼光,5分钟就把这问题发现了。可是发现了有什么用?得解决问题啊!

## 三、解决问题

开发小伙伴说:那我把所有的数据库表设计,id字段由Long类型改成String类型吧。我问他你有多少张表?他说100多张吧。

* 100多张表还有100多个实体类需要改

* 还有各种使用到实体类的Service层要改

* Service等改完Controller层要改

* 关键的是String和Long都是常用类型,他还不敢批量替换

小伙伴拿起电话打算订餐,说今晚的加班是无法避免了。我想了想说:你最好别改,**String做ID查询性能会下降**,我再想想!后端A到前端B出现精度丢失,要么改前端,要么改后端,要么…… 。“哎哎,你等等先别订餐,后端A到前端B你用的什么做的序列化?” 小伙伴告诉我说使用的是Jackson,这就好办了,Jackson我熟悉啊!

---

**解决思路:后端的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;

}

}

~~~

小伙伴放下电话, 再次投来敬佩眼光。“走吧,一起下班!”我和小伙伴说,小伙伴一路上一直问我你是怎么学习的?我冠冕堂皇的说了一些多想多学多问之类的话。

其实我心里在想:我是一个懒人,但我不能说。能躺着绝不坐着,能自动绝不手动,能打车绝不自己开车。第一次就把事情做对,才是省时省力做好的方法!这么多年的“懒”,决定了我需要去思考更多的“捷径”,思考“捷径”的过程是我不断进阶的诀窍!

**勤奋的人是社会的生产力,而懒人是社会的创造力!**

mybatis plus使用雪花算法_11.雪花算法与精度丢失相关推荐

  1. long 雪花算法_雪花算法(snowflake)

    简单描述 最高位是符号位,始终为0,不可用. 41位的时间序列,精确到毫秒级,41位的长度可以使用69年.时间位还有一个很重要的作用是可以根据时间进行排序.注意,41位时间截不是存储当前时间的时间截, ...

  2. java雪花_Java实现雪花算法(snowflake)

    本文主要介绍了Java实现雪花算法(snowflake),分享给大家,具体如下: 简单描述 最高位是符号位,始终为0,不可用. 41位的时间序列,精确到毫秒级,41位的长度可以使用69年.时间位还有一 ...

  3. 开源一个新的雪花算法(雪花漂移)

    IdGenerator 介绍 用一种全新的雪花漂移算法(以下简称本算法),让ID更短.生成速度更快. 核心在于缩短ID长度的同时,还能保持极高并发处理量(50W/0.1s),且具有很强配置能力. 需求 ...

  4. Ribbon默认负载均衡算法之轮训算法原理解析

    目录 此项目中用到的数据库脚本文件 父模块`cloud2020`中仅有一个`pom.xml`文件 项目结构图 `pom.xml`文件 1.创建一个微服务项目用来测试 1.1创建`cloud-api-c ...

  5. 条件随机场(CRF) - 4 - 学习方法和预测算法(维特比算法)

    声明: 1,本篇为个人对<2012.李航.统计学习方法.pdf>的学习总结,不得用作商用,欢迎转载,但请注明出处(即:本帖地址). 2,由于本人在学习初始时有很多数学知识都已忘记,所以为了 ...

  6. SURF算法与SIFT算法的性能比较——图像特征点检测与提取算法分析

    图像特征点提取算法的算法研究(SURF和SIFT算法) 1. 摘要 计算机视觉中,很大一部分研究集中在图像特征提取和特征生成算法上.对图像的优化,不同于一般数学问题的优化方法,图像的优化是对像素点,在 ...

  7. 数据结构与算法(5)字符串(BF算法、KMP算法及KMP算法优化)

    目录 一.BF算法(暴力算法) 二.KMP算法 三.KMP算法优化 一.BF算法(暴力算法) 一个一个往后匹配,匹配失败继续从母串下一个和头(子串的头)往后继续匹配. 虽然简单,但是需要较多的时间复杂 ...

  8. 大疆车载招聘|SLAM、地图定位、感知算法、机器学习算法工程师

    3D视觉工坊致力于推荐最棒的工作机会,精准地为其找到最佳求职者,做连接优质企业和优质人才的桥梁.如果你需要我们帮助你发布实习或全职岗位,请添加微信号「CV_LAB」. 公司介绍 大疆车载是大疆旗下专门 ...

  9. 标准K-means算法的缺陷、K-mean++初始化算法、初始化算法步骤、Kmeans++算法实现

    标准K-means算法的缺陷.K-mean++初始化算法.初始化算法步骤.Kmeans++算法实现 目录 标准K-means算法的缺陷.K-mean&

最新文章

  1. git获取指定release版本代码
  2. 学习笔记——sklearn监督学习:回归(简单数学知识罗列)
  3. MATLAB系统命令
  4. webpack入门与笔记
  5. 【转】C语言中DEFINE简介及多行宏定义
  6. Log4Net配置使用简记
  7. MPU和MCU的区别和选择
  8. java plug机制_【maven实战】20-插件解析机制
  9. ssm框架数据查询一直为null
  10. Uva 524 相邻素数全排列
  11. 用户如何设置浏览器主页的历史记录和管理加载项
  12. 送起来oracle,十一,送你 51 个 Oracle 常用语句~
  13. Chrome 手动清理缓存
  14. uniapp小程序分享转发功能
  15. MPB:南土所褚海燕组-土壤宏转录组学样本前处理与数据分析
  16. Android5.1浏览器证书问题
  17. 手机软键盘的发送按键和确认按键调用方法
  18. Vue+style 动态样式绑定(收藏图标)
  19. 伤寒杂病论.辨太阳病脉证并治(中)
  20. 【mcuclub】矩阵键盘

热门文章

  1. 工业机器人实训耗材_工业机器人实训室
  2. MATLAB学习笔记——二维和三维绘图
  3. 学习TeXworks编辑器(一)自定义快捷键详解
  4. 通过网络连接检测计算机病毒,网络安全习题及答案
  5. qt根据散点图拟合曲线_R可视化 | 散点图系列(1)
  6. Eclipse插件安装方式
  7. 宕机日志怎么看 thread detail_如何快速过滤出一次请求的所有日志?
  8. linux查看jdk详细版本号,Linux中查看jdk版本
  9. 背包问题——01背包问题——饭卡
  10. easyui 控制某列显示不显示_baogaiMCU控制OLED显示屏