我是靠谱客的博主 烂漫棉花糖,最近开发中收集的这篇文章主要介绍基于雪花算法解决Mybatis-Plus id主键生成的问题简要说明错误解决方案一解决方案二参考文章,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

简要说明

错误

解决方案一

1. 修改id字段类型

2. 调整数据库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)

Mybatis plus3.3.0的IdType介绍

package com.baomidou.mybatisplus.annotation;

import lombok.Getter;

/**
 * 生成ID类型枚举类
 *
 * @author hubin
 * @since 2015-11-10
 */
@Getter
public enum IdType {
    /**
     * 数据库ID自增
     */
    AUTO(0),
    /**
     * 该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
     */
    NONE(1),
    /**
     * 用户输入ID
     * <p>该类型可以通过自己注册自动填充插件进行填充,不设置的话默认是雪花算法</p>
     */
    INPUT(2),

    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
    /**
     * 分配ID (主键类型为number或string)
     *
     * @since 3.3.0
     */
    ASSIGN_ID(3),
    /**
     * 分配UUID (主键类型为 string)
     */
    ASSIGN_UUID(4),
    /**
     * @deprecated 3.3.0 please use {@link #ASSIGN_ID}
     */
    @Deprecated
    ID_WORKER(3),
    /**
     * @deprecated 3.3.0 please use {@link #ASSIGN_ID}
     */
    @Deprecated
    ID_WORKER_STR(3),
    /**
     * @deprecated 3.3.0 please use {@link #ASSIGN_UUID}
     */
    @Deprecated
    UUID(4);

    private final int key;

    IdType(int key) {
        this.key = key;
    }
}

雪花算法类com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator

雪花算法xml配置写法如下

mybatis-plus:
  #mapper-locations: classpath:mybatis/**/*Mapper.xml
  # 在classpath前添加星号可以使项目热加载成功<br>  # 自定义xml sql文件需要配置这个
  mapper-locations: classpath*:mybatis/**/*Mapper.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.nis.project
  global-config:
    #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
    id-type: 3
    #机器 ID 部分(影响雪花ID)
    workerId: 1
    #数据标识 ID 部分(影响雪花ID)(workerId 和 datacenterId 一起配置才能重新初始化 Sequence)
    datacenterId: 18
    #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
    field-strategy: 2
    #驼峰下划线转换
    db-column-underline: true
    #刷新mapper 调试神器
    refresh-mapper: true
    #数据库大写下划线转换
    #capital-mode: true
    #序列接口实现类配置
    #key-generator: com.baomidou.springboot.xxx
    #逻辑删除配置(下面3个配置)
    logic-delete-value: 0
    logic-not-delete-value: 1
    #自定义SQL注入器
    #sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
    #自定义填充策略接口实现
    #meta-object-handler: com.baomidou.springboot.xxx
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

雪花算法介绍 

 譬如当前的环境建设的内容是:四个环境处于四个不同的子网(dev、test、stg、prod),其中四个子网中的主机号最长的是16位,所以得到了下面的针对于AO部门所有pod的雪花ID结构

 

定长的思考

首先雪花算法本身是不能够保证ID定长的,所以要想达到定长的效果,需要额外处理一下。针对于要求定长18的场景。其最大id为:999999999999999999L,最小id为:100000000000000000L。

针对一个定长的id其能够支持的年数如下(另id最大值为maxId,最小值为minId,时间戳的偏移量为timestampShift,一年的秒数为yearSec):

yearNum = ((maxId >> timestampShift) - (minId >> timestampShift)) / yearSec

可以通过制定一个时间作为雪花id的开始时间,另当前时间和开始时间差值所产生的id为最小id即可保证id的最小值为指定长度,同时通过上面的公式可以计算出多少年之后产生的id不会超过固定位数。

  

参考文章

mybatis-plus id主键生成的坑___WanG的博客-CSDN博客_mybatisplus 自增id

最后

以上就是烂漫棉花糖为你收集整理的基于雪花算法解决Mybatis-Plus id主键生成的问题简要说明错误解决方案一解决方案二参考文章的全部内容,希望文章能够帮你解决基于雪花算法解决Mybatis-Plus id主键生成的问题简要说明错误解决方案一解决方案二参考文章所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部