91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

大數據中如何解決雪花算法ID到前端之后精度丟失問題

發布時間:2021-12-07 11:08:09 來源:億速云 閱讀:572 作者:柒染 欄目:大數據

大數據中如何解決雪花算法ID到前端之后精度丟失問題,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

最近公司的一個項目組要把以前的單體應用進行為服務拆分,表的ID主鍵使用Mybatis plus默認 的雪花算法來生成。

快下班的時候,小伙伴跑過來找我,:“快給我看看這問題,卡這卡了小半天了!”。連拉帶拽,連哄帶騙的把我拉到他的電腦前面。這位小伙伴在我看來技術不算是大牛,但經驗也很豐富了。他都卡了半天的問題,應該不是小問題,如果我一時半會搞不定,真的是耽誤我下班了,所以我很不情愿的在他的位置坐了下來。

一、現象是這樣的

下面我把異常的現象給大家描述一下,小伙伴建了一張表,表的主鍵是id BigINT,用來存儲雪花算法生成的ID,嗯,這個沒有問題!

CREATE TABLE user
(
	id BIGINT(20) NOT NULL COMMENT '主鍵ID',
        #其他字段省略
);

使用Long 類型對應數據庫ID數據。嗯,也沒有問題,雪花算法生成的就是一串數字,Long類型屬于標準答案!

[@Data](https://my.oschina.net/difrik)
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](https://my.oschina.net/pointdance)
public class JacksonConfig {

  [@Bean](https://my.oschina.net/bean)
  [@Primary](https://my.oschina.net/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;
  }

}

小伙伴放下電話, 再次投來敬佩眼光。“走吧,一起下班!”我和小伙伴說,小伙伴一路上一直問我你是怎么學習的?我冠冕堂皇的說了一些多想多學多問之類的話。 其實我心里在想:我是一個懶人,但我不能說。能躺著絕不坐著,能自動絕不手動,能打車絕不自己開車。第一次就把事情做對,才是省時省力做好的方法!這么多年的“懶”,決定了我需要去思考更多的“捷徑”,思考“捷徑”的過程是我不斷進階的訣竅!

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

五指山市| 天气| 临颍县| 墨脱县| 闵行区| 南江县| 炉霍县| 泽库县| 四子王旗| 固镇县| 繁昌县| 连南| 宝兴县| 舞钢市| 阜宁县| 特克斯县| 呈贡县| 马山县| 青冈县| 巫山县| 抚州市| 花莲县| 古田县| 广元市| 丰镇市| 太湖县| 方城县| 临澧县| 余庆县| 富顺县| 红安县| 金堂县| 山东省| 洪洞县| 呼伦贝尔市| 伊金霍洛旗| 阳高县| 交口县| 榕江县| 南城县| 民勤县|