問題の説明
Java バックエンド Long 型の範囲
- ##-2^63~2^63、つまり -9223372036854775808~9223372036854775807 、これは
の 19 桁目です。
この数値は、Long.MAX_VALUE、Long_MIN_VALUE メソッドを通じて取得できます。
##-2^53~2^53、つまり: -9007199254740991 ~9007199254740991、これは
- 16 ビット
- です。
この数値は、Number.MAX_SAFE_INTEGER、Number.MIN_SAFE_INTEGER メソッドを通じて取得できます。
- 結論
Java バックエンドの Long width がフロントエンドの Long width よりも大きいことがわかります。スノーフレーク アルゴリズムは通常、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
データベース ID の BIGINT 型に対応するには Long 型を使用します。
ここでは、MybatisPlus のスノーフレーク アルゴリズムを使用して、19 桁の純粋な数値を主キー ID として自動的に生成します。 (もちろん、スノーフレーク アルゴリズムを使用して ID を手動で生成することもできます)import lombok.Data; @Data public class User { @TableId(type = IdType.ASSIGN_ID) private Long id; //其他成员 }
3. フロント エンドへの応答
JSON データでフロント エンドへの応答正常です
{ "id": 1352166380631257089, ... }問題の説明インスタンスコントローラ
package com.knife.controller; import com.knife.entity.UserVO; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("user") public class UserController { @GetMapping("find") public UserVO find(Long id) { UserVO userVO = new UserVO(); userVO.setId(id); userVO.setUsername("Tony"); return userVO; } }エンティティ
package com.knife.entity; import lombok.Data; @Data public class UserVO { private Long id; private String username; }テストアクセス: http ://localhost:8080/user/find ?id=1352213368413982722結果
問題の再発
なぜ問題がないのでしょうか?
フロント エンドがバック エンドに渡される: SpingMVC は String 型 ID を Long 型に自動的に変換しますので、問題はありません。バック エンドはフロント エンドに応答します。 JSON 形式なので、JS とは関係がなく、問題ありません。
フロントエンドは JSON を受信した後、それを JS オブジェクトにシリアル化し、他の操作を実行します。 JSON を JS オブジェクトに変換するときに、次のような問題が発生します。
ご覧のとおり、元の ID は 1352213368413982722 で、JS オブジェクトにシリアル化された後、 1352213368413982700
になります。
コードは次のとおりです。const json = '{"id": 1352213368413982722, "name": "Tony"}'; const obj = JSON.parse(json); console.log(obj.id); console.log(obj.name);

次の 2 つの解決策があります。
ID フィールドを変更します。データベースのテーブル設計をLong型からString型へ。
#フロントエンドは精度を維持するために String 型を使用して ID を保存し、バックエンドとデータベースは引き続き Long (BigINT) 型を使用します- オプション 1 では String 型を使用します。データベース ID を実行すると、クエリのパフォーマンスが大幅に低下します。したがって、オプション 2 を採用する必要があります。この記事ではオプション 2 を紹介します。
- 方法 1: グローバル処理 はじめに
package com.knife.config; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; @Configuration public class JacksonConfig { @Bean public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.createXmlMapper(false).build(); // 全局配置序列化返回 JSON 处理 SimpleModule simpleModule = new SimpleModule(); // 将使用String来序列化Long类型 simpleModule.addSerializer(Long.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); objectMapper.registerModule(simpleModule); return objectMapper; } }テスト アクセス: http://localhost:8080/user/find?id=1352213368413982722
オプション 2: カスタム シリアライザー (非推奨)
シリアライザー
package com.knife.config; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.ser.std.NumberSerializer; import java.io.IOException; /** * 超出 JS 最大最小值 处理 */ @JacksonStdImpl public class BigNumberSerializer extends NumberSerializer { /** * 根据 JS Number.MAX_SAFE_INTEGER 与 Number.MIN_SAFE_INTEGER 得来 */ private static final long MAX_SAFE_INTEGER = 9007199254740991L; private static final long MIN_SAFE_INTEGER = -9007199254740991L; /** * 提供实例 */ public static final BigNumberSerializer instance = new BigNumberSerializer(Number.class); public BigNumberSerializer(Class<? extends Number> rawType) { super(rawType); } @Override public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException { // 超出范围 序列化位字符串 if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) { super.serialize(value, gen, provider); } else { gen.writeString(value.toString()); } } }
ObjectMapper 構成
package com.knife.config; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; @Configuration public class JacksonConfig { @Bean public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.createXmlMapper(false).build(); // 全局配置序列化返回 JSON 处理 SimpleModule simpleModule = new SimpleModule(); // 将使用自定义序列化器来序列化Long类型 simpleModule.addSerializer(Long.class, BigNumberSerializer.instance); simpleModule.addSerializer(Long.TYPE, BigNumberSerializer.instance); objectMapper.registerModule(simpleModule); return objectMapper; } }テスト
次を参照してください。 http://localhost:8080/user/find?id=1352213368413982722
方法 2: ローカル処理
手順例
package com.knife.entity; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import lombok.Data; @Data public class UserVO { @JsonSerialize(using= ToStringSerializer.class) private Long id; private String username; }テストアクセス: http://localhost:8080/user/find?id=1352213368413982722
以上がSpringBootスノーフレークアルゴリズムの主キーIDがフロントエンドに送信された後の精度損失の問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

Dreamweaver Mac版
ビジュアル Web 開発ツール

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

WebStorm Mac版
便利なJavaScript開発ツール
