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存储引擎的索引与记录结构是这样的:
其索引与记录的结构是这样的:
(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”);
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341