Mybatis-Plus自动生成的数据库id过长的解决

 更新时间:2021年12月03日 14:40:44   作者:lilun1231  
这篇文章主要介绍了Mybatis-Plus自动生成的数据库id过长的解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Mybatis-Plus自动生成的数据库id过长

一、问题

作为一名第一次使用mybatis-plus的萌新开发工程师,在项目开发过程中遇到一个问题。

当使用mybatis-plus自带的mybatis-generate生成DO文件,如下图所示

在这里插入图片描述

DO类由注释@Table修饰,主键id由注释@Id,@GeneratedValue修饰。但是使用这样的默认DO进行数据库操作时,会有导致数据库自动生成的主键id过长,如下所示

在这里插入图片描述

这样的19位id,会存在一些问题:

1)前端拿到这样的id后,会发生Number精度丢失,导致id数值发生变化,使得前后端的id不一致,这样就使得无法利用id进行操作

2)InnoDB存储引擎的索引与记录结构是这样的:

其索引与记录的结构是这样的:

img

(1)主键索引与记录存储在一起;InnoDB通过主键索引查询时,能够直接定位到行记录。

(2)普通索引存储主键(这下不是指针了);

这样当主键id是一个比较长的数值时每个索引都存储这个值,在数据量大,内存珍贵的情况下,MySQL有限的缓冲区,存储的索引与数据会减少,索引占用的磁盘空间也会增加,磁盘IO的概率会增加。

二、解决方案

通过询问各位师兄和开发同学,解决了这个问题,解决方案如下:

在这里插入图片描述

将DO类的注释改为@TableName,主键id的注释改为@TableId,这样自动生成的主键id就是正常位数。

至于为什么会这样,我通过查阅资料得出一下结论

三、原理

1.首先了解下@GeneratedValue的使用。@GeneratedValue属于JPA注解之一,JPA通过annotation来映射hibernate实体,基于annotation的hibernate主键标识为@Id,其生成规则是由@GeneratedValue设定的。

JPA提供四种标准用法,由@GeneratedValue的源代码可以明显看出:

@Target({METHOD,FIELD})    
    @Retention(RUNTIME)    
    public @interface GeneratedValue{    
        GenerationType strategy() default AUTO;    
        String generator() default "";    
    }  

其中GenerationType包含四种策略:

public enum GenerationType{    
  //使用一个特定的数据库表格来保存主键。 
    TABLE,
  //根据底层数据库的序列来生成主键,条件是数据库支持序列。 
    SEQUENCE,
  //主键由数据库自动生成(主要是自动增长型) 
    IDENTITY,
  //主键由程序控制。
    AUTO;
  
    private GenerationType() {
    }
} 

其中的AUTO类型,在指定主键时,如果不指定主键生成策略,默认为AUTO。

@Id # 默认生成策略为AUTO

效果等同于

@Id  
@GeneratedValue(strategy = GenerationType.AUTO) 

由此可见,自动生成的id和注解没什么关系,那也许就是mybatis-plus的主键生成逻辑问题了。

通过去查询mybatis-plus的文档(文档链接:https://baomidou.gitee.io/mybatis-plus-doc/#/spring-boot

在这里插入图片描述

发现mybatis-plus默认的主键生成是全局唯一的UUID,会导致生成的id过长。

并且官方也提供了解决方法,如下图

在这里插入图片描述

可这只是将防止了前端接收时的精度丢失,并没有解决我的问题。

根据文档,可以得出一个新的解决办法,并且不用更改DO类代码:

将文档中所说的id-type配置设置为0即可。

Mybatis-Plus id主键生成的问题

简要说明

由于mybatis-plus会自动插入一个id到实体对象, 不管你封装与否, 所以有时候导致一些意外的情况发生

默认是生成一个长数字字符串(编码不同可能结尾带有字母)

错误

ested exception is org.apache.ibatis.reflection.ReflectionException: Could not set property 'id' of 'class com.xxx' with value '1110423703487479810' Cause: java.lang.IllegalArgumentException: java.lang.ClassCastException@14041406

大致就是由于自动生成了一个id1110423703487479810, 但是无法放入到integer中

解决方案一

1. 修改id字段类型

将id字段类型改为long, 这样就能保证有足够位数放入生成的id

2. 调整数据库id字段类型

将数据库的id字段的长度(改为20位)

解决方案二

如果想要使用id自增的, 就需要把mybatis-plus这个id生成的功能给关掉

添加注解

在id字段上加上如下注解即可

@TableId(value = "id",type = IdType.AUTO)

其他type类型介绍

  • AUTO:AUTO(0, “数据库ID自增”),
  • INPUT:INPUT(1, “用户输入ID”),
  • ID_WORKER:ID_WORKER(2, “全局唯一ID”),
  • UUID:UUID(3, “全局唯一ID”),
  • NONE:NONE(4, “该类型为未设置主键类型”),
  • ID_WORKER_STR:ID_WORKER_STR(5, “字符串全局唯一ID”);

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java实现微博后台登录发送微博

    java实现微博后台登录发送微博

    这篇文章主要为大家详细介绍了java实现微博后台登录发送微博的相关资料,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • Java锁擦除与锁粗化概念和使用详解

    Java锁擦除与锁粗化概念和使用详解

    这篇文章主要介绍了Java锁擦除与锁粗化概念和使用,锁擦除的主要判定依据来源于逃逸分析的数据支持,如果判断在一段代码中,堆上的所有数据都不会逃逸出去从而被其他线程访问到,那就可以把它们当做栈上数据对待,认为它们是线程私有的,同步加锁自然就无须进行
    2023-02-02
  • 浅谈servlet3异步原理与实践

    浅谈servlet3异步原理与实践

    本篇文章主要介绍了servlet3异步原理与实践,详细的介绍了servlet和异步的流程使用,具有一定的参考价值,有兴趣的可以了解一下
    2017-10-10
  • 详解Java的内存模型

    详解Java的内存模型

    本文更准确的说法应该是JVM的内存模型,但是这里又牵扯了一些其他的前置知识,主要是想从Java入手,从源头上梳理一遍整个Java底层运行的机制,中间会额外补充一些和题目无关的前置基础,导致主讲内存模型的篇幅所占的比例就不是那么绝对。
    2021-06-06
  • Java中的HashMap为什么会产生死循环

    Java中的HashMap为什么会产生死循环

    这篇文章主要介绍了Java中的HashMap为什么会产生死循环,HashMap 死循环是一个比较常见、比较经典的问题,下面文章我们就来彻底理解死循环的原因。需要的小伙伴可以参考一下
    2022-05-05
  • java提高篇(二三)-----HashMap详解

    java提高篇(二三)-----HashMap详解

    HashMap基于哈希表的 Map 接口的实现,本篇文章主要讲诉了java中HashMap,有兴趣的可以了解一下。
    2016-11-11
  • Netty分布式ByteBuf使用的回收逻辑剖析

    Netty分布式ByteBuf使用的回收逻辑剖析

    这篇文章主要介绍了Netty分布式ByteBuf使用的回收逻辑剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03
  • Elasticsearch8.1中的Script使用实例深入解读

    Elasticsearch8.1中的Script使用实例深入解读

    这篇文章主要为大家介绍了Elasticsearch8.1中的Script使用实例深入解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Java设计模式中的七大原则详细讲解

    Java设计模式中的七大原则详细讲解

    本篇文章主要对Java中的设计模式如,创建型模式、结构型模式和行为型模式以及7大原则进行了归纳整理,需要的朋友可以参考下,希望能给你带来帮助
    2023-02-02
  • 通过Java设置Word页面背景色过程详解

    通过Java设置Word页面背景色过程详解

    这篇文章主要介绍了通过Java设置Word页面背景色过程详解,Word中可以针对不同文档排版设计要求来设置背景设置颜色。常见的可设置单一颜色、渐变色或加载图片来设置成背景。下面通过Java来设置以上3种Word页面背景色,需要的朋友可以参考下
    2019-07-07

最新评论