Java开发 - 消失的id

Java开发改了MySQL表后,所有的索引都消失了 但当一些耗时SQL执行时,就会出现同步延迟。重新考虑这个问题,我们需要保留的数据仅仅只有千万中的不到10万条非bad_group的数据,因此除了删除bad_group数据这种方法,更简单的是将有效数据先copy到一张临时表中,然后drop原表,再重新创建表,将临时表中数据拷贝回来。按照这个思路,回忆起之前在日常环境写假数据的时候,如果指定了一个比较大的id,那么后续所有新数据都会在这个id基础上生成(比如当前表中只有10条记录,id=10,插入一条id=100的数据,后续数据就会接着id=101继续生成。 阅读详情

目录

前言

问题描述

问题分析

解决方案

创建对象转换器

扩展原对象转换器

结语


前言

开发时,我们经常会遇到一些奇奇怪怪的问题,明明一切流程都是正确的,但却得不到正确的结果,这让我们很是苦恼,本系列博客将带你一起见识这些开发中存在的灵异事件,让我们一起解密他们,作为本系列的第一篇博客,我很荣幸的给大家介绍这篇消失的id。

问题描述

由于部分需求下,我们采用了雪花算法等算法自动生成id,这也就导致了id很长,通过mvc框架的转换器序列化后返回客户端后,当客户端拿着我们返回的id去获取信息的时候竟然提示数据库没有此id,真是见鬼了?

问题分析

首先,我们通过查看控制台输出SQL发现,用户传入的id的确和数据库中的id有差异。由于此情况发生在分页查询时,我们来想想分页查询会发生什么:

服务端将返回给客户端的对象进行json序列化,将数据转换为json格式的数据,而我们实体类中的id是一个Long类型的数据,由于使用了雪花算法生成id,id的长度都是19位。

逻辑流程都没错,这好像没什么不妥啊?那问题究竟出在哪里呢?

有没有一种可能,问题不一定出在后端这里,那我们不妨从移动端入手找找原因?

经过我们通过对一个19位数字的普通输出发现:js在对长度较长的长整型数据进行处理时,会损失精度, 从而导致提交到后端的id和数据库中的id不一致。

原来如此,也就是在移动端接收到数据的那一刻起,也许是在编译器的作用下,这种精度的损失就开始了,有没有一种方式,可以使数据在传递的过程中不会因为数据的转化导致精度缺失呢?

别说,还真有:字符串!果然是万能的字符串啊,所以下一步,我们就需要让数据在传给前端的时候,id这类长整型数据可以转化为String类型。那有没有这种方法可以快捷方便的实现呢?

要想知道有没有此方法,我们还是要从转化本身着手,由于在SpringMVC中, 将Controller方法的返回值转换为json是通过jackson来实现的,它内部涉及到SpringMVC中的一个消息转换器:MappingJackson2HttpMessageConverter,所以我们可以从这个转换器入手,看看能不能对这个转换器进行扩展。

我们很幸运,SpringMVC允许我们对这个转换器进行扩展!!!

解决方案

要想扩展,我们首先需要创建一个新的转换器来替换原来的转换器。

创建对象转换器

package com.codingfire.config;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

/**
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {

    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    public JacksonObjectMapper() {
        super();
        //收到未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        //反序列化时,属性不存在的兼容处理
        this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);


        SimpleModule simpleModule = new SimpleModule()
                .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))

                .addSerializer(BigInteger.class, ToStringSerializer.instance)
                .addSerializer(Long.class, ToStringSerializer.instance)
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));

        //注册功能模块 例如,可以添加自定义序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}

从代码中,我们看到除了对长整型数据进行转化外,还有对BigInteger,LocalDate,LocalTime等类型数据的转化。 

扩展原对象转换器

下一步,我们需要让我们新写的转换器工作,我们需要重写一个叫extendMessageConverters的方法,该方法出现在WebMvcConfig类中,此类是一个自定义的配置类,它继承了WebMvcConfigurationSupport类,所以,我们在WebMvcConfig类中重写extendMessageConverters方法即可。

/**
 * 扩展mvc框架的消息转换器
 * @param converters
 */
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    log.info("扩展消息转换器...");
    //创建消息转换器对象
    MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
    //设置对象转换器,底层使用Jackson将Java对象转为json
    messageConverter.setObjectMapper(new JacksonObjectMapper());
    //将上面的消息转换器对象追加到mvc框架的转换器集合中
    converters.add(0,messageConverter);
}

一定要放在第一位,在程序里是第0位,这样才能让它生效。 

结语

到此,这个问题被解决了。这是开发中一个很小的问题,稍不留神就可能造成这种严重的影响,问题是还不好发现,新手往往会对此类问题束手无策,我们需要做的就是:只要时间的堆积和经验的积累,从一只菜鸟成为一只老鸟。开发没有捷径可走,如同人生,需要一步步坚定的走下去。我是CodingFire,你的良师益友,看到这里,很高兴能帮到你,咱们下篇再见。

WSL Ubuntu20 通过1Panel配置SSH服务的完整避坑指南 本文详细介绍了在WSL Ubuntu20环境下通过1Panel配置SSH服务的完整指南,包括环境准备、SSH服务安装与基础配置、1Panel中的SSH管理技巧以及连接测试与故障排查。特别针对WSL特性提供了避坑建议,如IP动态变化处理、SSH服务初始化配置等关键步骤,帮助用户高效搭建稳定的SSH服务环境。 阅读详情

相关推荐

【Allegro学习笔记】常规标贴封装创建-0402封装创建实例

摘要 本文主要介绍如何使用Allegro制作表面贴装封装。 所使用的软件 使用Allegro制作常规贴片封装主要使用的软件有Pad Designer和Allegro 1 0402类封装制作 1.1 0402类封装焊盘分析 0402封装尺寸图如图1...

Honglong 1万+

在java项目中的_id被fastjson转为json时丢失了(转载)

fastjson是阿里开发的一个javaBean和json解析器和封装器(源码位置),用过几次感觉挺好用的,也是国人的开源项目当然得支持,但最近项目在使用mongodb作为数据库时出现了_id丢失的问题,现将我遇到的问题和解决办法展示一下。 现将错误的程序代码添加上,然后再提供解决方法: package org.jivesoftware.openfire.plugin.friends.test; import org.bson.types.ObjectId; import org.jivesoftwar

weixin_42267549的博客 872

从VoLTE高清通话到5G新通话:手把手带你用Wireshark抓包分析QCI 1, 2, 5, 9的建立与切换过程

本文详细解析了从VoLTE高清通话到5G新通话的QCI(QoS Class Identifier)建立与切换过程,通过Wireshark抓包实战演示如何分析QCI 1、2、5、9的承载机制。内容涵盖QCI基础概念、实验环境搭建、VoLTE通话建立过程分析以及5G新通话中的QoS演进,为网络工程师和通信技术爱好者提供实用的技术指南和优化建议。

weixin_30788619的博客 343

获取缺失的最小id用于插入下一条数据(mysql)

获取mysql缺失的id的SQL语句分析笔记 文章目录获取mysql缺失的id的SQL语句分析笔记需求如何找到空缺的ID创建测试数据执行目标语句执行修改语句分析一下语句1. 笛卡尔积WERE语句 需求 工作中需要给设备添加编号,但是位数比较少。 编号有可能经常的批量的添加和删除,使用单纯的自增值作为主键, 有限的编号位数很快会用完,所以需要找到已经删除的ID, 使用空缺的ID进行插入。 如何找到空缺的ID 百度所以找一下就找到一个帖子,应该是看的人比较多。 网上找了篇梯子解决我遇到的问题: https://

yjkhtddx的专栏 534

Diffusion、VAE与GAN:三大生成模型的原理对比与应用场景解析

本文深入解析了Diffusion、VAE与GAN三大生成模型的核心原理与特性。Diffusion模型通过逆向去噪过程实现高质量图像生成,但计算成本较高;VAE擅长学习概率潜空间,训练稳定但图像偏模糊;GAN通过对抗训练生成锐利图像,但存在模式崩溃风险。文章结合实战场景,为图像生成、修复、超分辨率等任务提供了清晰的模型选择指南。

weixin_29063979的博客 346

RL调参侠之BipedalWalker BipedalWalkerHardcore SAC

前几天用PPO训练了个很一般的agent: RL调参侠之BipedalWalker PPO 我看SpinningUp上面说PPO和SAC是两个领域里各自的State_of_the_art的方法,所以就打算跑SAC试试看,之前因为Open AI Five的原因,一直感觉PPO很牛掰,实际上现在很多自动驾驶的算法也是用PPO在跑,毕竟有一个“必定能够提升期望”的理论保证在这里,我理解这对做项目很大的诱惑。 不过我跑出来的结果明显是SAC更好。 调参侠时间 策略熵的权重alpha用的0.2,我一开始没有看SAC的

weixin_48370148的博客 2102

用sql语句获取连续整数id中,缺失的最小id和最大id

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33889665的博客 1114

InSAR_ISCE软件数据处理流程之:利用哨兵数据获取2015年尼泊尔地震同震形变场

ISCE软件数据处理流程之:利用哨兵数据获取2015年尼泊尔地震同震形变场 ISCE软件做干涉只需要将数据准备好,并配置好insarApp.xml文件即可进行。 一、数据准备 1、SAR数据获取 本利中使用的数据为欧空局提供的sentinel-1A/B数据,可从阿拉斯加数据服务器上下载,具体下载方法可参考: 哨兵数据下载方法. 2、哨兵卫星轨道文件下载 哨兵数据处理除了需要SAR影像外,还需提供轨道参数文件,可从https://qc.sentinel1.eo.esa.int/aux_poeorb/下载。下载

weixin_42128764的博客 1万+

SpringBoot后端实体通过@RequestBody接收传进来的json为Null的解决办法

楼主今天在开发后端接口的时候,遇到了一个伤脑筋的问题,看下图: 楼主用@RequestBody注解通过实体去接收前端的json值,前端json值和实体TerminalPosition一一对应的,结果发现怎么传terminalPosition这个对象都为空,很奇怪; 楼主做实验发现把@RequestBody TerminalPosition terminalPosition 改成 @Requ...

弗兰-随风小欢的博客 9万+

RPG MV游戏数据修改指南:从JSON解析到脚本进阶

游戏数据修改是游戏开发与逆向工程中的常见实践,其核心原理在于解析和操作游戏资源文件。许多现代游戏引擎采用结构化数据格式(如JSON)存储游戏配置,这为外部修改提供了可能。通过理解文件结构、数据格式与游戏逻辑的关联,开发者或爱好者可以调整游戏平衡、修复问题或实现个性化定制,这不仅能深化对游戏设计机制的理解,也具备实际的技术学习价值。本文以基于Web技术栈的RPG Maker MV(RPG MV)引擎为例,其游戏数据多以明文JSON存储,结构清晰。文章将具体阐述如何安全地修改角色属性、物品效果、敌人数据及技能公

weixin_29001419的博客 408

【Bug已解决】claude: command not found 解决方案

方案适用场景推荐指数添加 PATH全局 bin 目录确实存在但未加入 PATH⭐⭐⭐⭐⭐nvm 重新安装多 Node 版本切换导致失效⭐⭐⭐⭐⭐Windows 环境变量检查Windows 平台专用⭐⭐⭐⭐原生安装脚本想彻底避开 npm PATH 问题⭐⭐⭐⭐清理多重 Node 安装系统里有多套 Node 管理方式冲突⭐⭐⭐报错的核心是npm 全局安装的可执行文件路径没有正确出现在系统的 PATH 环境变量里,而不是安装本身失败了。

一键难忘的博客 1万+

java bean为空_@RequestBody为JavaBean对象注入字段值为空的解决办法

在做一个项目时用到@RequestBody注解为请求信息做封装处理,发现对象中一个字段QQ(文档中请求json串的这个字段名首字母是大写的,风格迥异)被注入为null,没找到什么原因导致的。后来上网查阅了相关资料,拍脑袋一想,对啊。。。spring框架在对对象进行处理的时候还是要拿我们的get/set方法,我们把对象的字段名首字母搞成大写,这让spring在处理的时候到底是为QQ还是qQ这个字段赋...

weixin_32821579的博客 828

9、自动定理证明的发展历程与关键技术

本文全面介绍了自动定理证明的发展历程、关键技术及其实际应用,包括消解原理、参数化、支撑集策略等核心方法,并探讨了算法优化、数据结构优化及并行计算等提升效率的手段。同时,文章展望了未来发展方向,如深度学习在定理证明中的应用、交互式定理证明以及高阶逻辑的研究前景。

ll5678的博客 508

clean r.java_项目clean之后,R.java不见了

今天新增了一个安卓项目,刚做完布局,发现有个R.id找不到了,于是clean了一下,这下出问题了,发现各处的R.id都找不到,报错。结果一看是R.java没了然后是各种百度,有说重新clean的,有说 Android Tools -> fix project propertities的,不过都不起作用。然后继续百度,看到一个普遍的观点是说,只要xml文件有问题,那系统是绝对不会为你自动生成R...

weixin_36012215的博客 126

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Android R.java文件丢失

在编写Android的界面activity_main.xml文件时,R.java消失。 原因:activity_main.xml中例如:android:layout_alignLeft="@id/et_content",在@后面无“+”. 在Graphical Layout界面中拖完控件后,在activity_main.xml中,所有"@+id"组合中“+”号最好不要去掉(有的项目中建议去掉)

lyw603267094的专栏 502

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

怎么在idea中引入websocket_解决 IntelliJ IDEA 使用过程中让你觉得不爽的一些问题...

1.每次导入一个新的 Project 项目的时候已经配置好的 maven 被还原为默认状态如果 idea 的版本比较老的话看到的是这样的然后再修改 Maven 配置就可以了2.在创建或者导入 Maven 项目后,编写代码的时候总是提示不支持 Java8,编译也无法通过 我们查看 settings -> java compiler 发现编译版本是 1.8 之前的版本解决方案:在 po...

weixin_39562234的博客 2207

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Android源码开发之横屏actionbar的title消失

最近遇到一个bug,虽然看起来简单,实则不是那么回事 设置----语言和输入法----个人字典,进去,竖屏的时候actionbar上显示个人字典,但当横屏的时候,title突然消失 定位到Setting/src/com/android/settings/inputmethod/UserDictionaryList.java 在onResum里         getActivity().g

华歌诗的博客 1140

如果明天 Spring 框架突然从世界上消失,Java 会发生什么?

在开发圈子有一条隐形的鄙视链:C++ 看不起 Java,Go 看不起 Java,有时候连 Java 程序员自己都看不起 Java。但奇怪的是,尽管被骂了这么多年,Java 依然稳坐企业级开发的头把交椅。是因为 Java 语法优美吗?是因为 JVM 性能无敌吗?都不是。答案可能比你想象的更残酷:Java 不会死,但它会迅速“凉”透,退化成下一个 COBOL。

sjkflw121150的博客 590

Java学习--------消息队列的重复消费、消失与顺序性的深度解析​

在不同场景下,带来的后果也十分严重,如在金融领域会导致出现重复扣款、重复转账的问题,从而引发资损和用户投诉。​在库存管理系统中会导致重复扣减库存,从而出现超卖或负库存。例如,使用 Spring Kafka 消费支付消息时,若处理逻辑未做防护,可能导致用户账户被重复扣款,这在金融场景中是致命的。消费者 ACK 机制误用:例如:Spring Kafka 默认ack-mode=BATCH,若消费者处理消息后未及时提交 offset,重启后会重复消费批次内消息。任务调度失效:定时任务触发消息丢失,导致任务漏执行。

shouxifeiwu的博客 991

Java游戏开发——连连看

游戏介绍:       “连连看”是一款来源于我国台湾的桌面小游戏,主要考验的是玩家们的眼力,在有限的时间内,只要能把所有能连接的相同图案,两个两个的找出来,每找到一对,它们就会自动消失,只要能把所有的图案全部消完即可获得胜利。所谓能够连接,是指无论横向还是纵向,从一个图案到另一个图案之间的连线拐角不能超过两个(中间的直线不超过三根),其中连线不能从尚未消去的图案上经过。 本次开发的连连看游戏...

墨染秦月的博客 2万+

android获取组件id,安卓组件id属性 Android 提示框获取组件ID

android组件资源id为0说明什么Android 提示框获取组件IDnew AlertDialog.Builder(MainActivity.this) .setTitle("请输入" ) .se嗯,你难道不会拿个容器存起来?为什么一定要拿到他的ID呢. EditText tempEdt = new EditText(MainActivity.this);android中设置为INVISIBL...

weixin_32827773的博客 816

r.java不自动更新id_安卓项目R,java文件不能自动更新,clean之后,R.java消失 (转自 Cynosure鱼)...

今天整了个安卓项目,新增加了个跳转页面,添加完背景图,发现有个R.id找不到了,于是clean了一下,这下出问题了,发现各处的R.id都找不到,报错。结果一看是R.java没了然后各种百度结果:有说重新clean的,有说 Android Tools -> fix project propertities的,不过都不起作用。然后继续百度,看到一个普遍的观点是说,只要xml文件有问题,那系统是绝...

weixin_40001245的博客 152

ListView中CheckBox选中刷新消失问题解决方案一

此demo存在一点问题,就是如果点击单个CheckBox刷新后还是会消失,闲话不说线上代码 main.xml<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fi

2112

R.layout 找不到指定的id【安卓开发】

今天增加了一个新的安卓项目,刚开始配置布局文件就出了点小问题,经过几次clean之后,报错了,原来的R.layout.fragment_run是能找到的,但现在划红线,说找不到了:但是打开R.java,这个fragment_run却是存在的:这是怎么回事?百度了一下,很快找到了和这个相似的情况,原来是R.java的引用问题,因为之前的折腾过程中,R.java消失了,后来重新生...

weixin_33688840的博客 199

java关于按钮的api,java – 按钮文本消失在KitKat(API级别19)

我的应用程序(一个游戏)的主菜单使用标准的Android按钮.除了Nexus 7与Android 4.4.2之外,所有设备都可以正常工作.问题如下:在任何一种情况下,按钮的文本突然消失:>按钮被按下(当我触摸它时立即发生,不需要释放它)> setEnabled(boolean)被调用在按钮上例如,如果我按“加载游戏”,按钮在新闻事件期间正确突出显示,但“加载游戏”完全消失(该按钮有空文...

weixin_39631755的博客 86
上一篇: Java开发 - MybatisPlus框架初体验
下一篇: Java开发 - SpringCache初体验
CodingFire
CodingFire  2022年度博客之星移动开发领域TOP 5 2022年度博客之星移动开发领域TOP 5 领域专家: 移动开发技术领域 领域专家: 移动开发技术领域
博客等级 码龄11年 7927粉丝 387原创
评论 34
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodingFire

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值