mybatisplus使用雪花id通过swagger返回ID时精度丢失问题

xml 复制代码
在使用mybatisplus自带雪花的时候会发现返回的ID是19位的长度,因此在通过swagger页面展示的时候会发现后端返回的和页面展示的ID不一致问题。是因为精度丢失的问题。因此需要更改雪花ID的长度


xml 复制代码
跟踪进去:


发现是DefaultIdentifierGenerator类实现了IdentifierGenerator并重写了nextId方法,因此需要我们重写nextId方法

  • 进行重写:
java 复制代码
package com.ssdl.config.automatic;

import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.ssdl.util.IdGenerator;
import org.springframework.stereotype.Component;

@Component
public class CustomerIdGenerator implements IdentifierGenerator {
    @Override
    public Number nextId(Object entity) {
        return IdGenerator.generateId();
    }
}
java 复制代码
package com.ssdl.util;

import java.util.Date;
import java.util.UUID;
 
/**
 * compressed id generator, result id not great than 53bits before 2318-06-04.
 */
public class IdGenerator {
 
    private static IdGenerator instance = new IdGenerator(0);
 
    public static IdGenerator initDefaultInstance(int machineId) {
        instance = new IdGenerator(machineId);
        return instance;
    }
 
    public static IdGenerator getInstance() {
        return instance;
    }
 
    public static long generateId() {
        return instance.nextId();
    }
 
    // total bits=53(max 2^53-1:9007199254740992-1)
 
    // private final static long TIME_BIT = 40; // max: 2318-06-04
    private final static long MACHINE_BIT = 5; // max 31
    private final static long SEQUENCE_BIT = 8; // 256/10ms
 
    /**
     * mask/max value
     */
    private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
    private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
 
    private final static long MACHINE_LEFT = SEQUENCE_BIT;
    private final static long TIMESTMP_LEFT = MACHINE_BIT + SEQUENCE_BIT;
 
    private long machineId;
    private long sequence = 0L;
    private long lastStmp = -1L;
 
    private IdGenerator(long machineId) {
        if (machineId > MAX_MACHINE_NUM || machineId < 0) {
            throw new IllegalArgumentException(
                    "machineId can't be greater than " + MAX_MACHINE_NUM + " or less than 0");
        }
        this.machineId = machineId;
    }
 
    /**
     * generate new ID
     *
     * @return
     */
    public synchronized long nextId() {
        long currStmp = getTimestamp();
        if (currStmp < lastStmp) {
            throw new RuntimeException("Clock moved backwards.  Refusing to generate id");
        }
 
        if (currStmp == lastStmp) {
            sequence = (sequence + 1) & MAX_SEQUENCE;
            if (sequence == 0L) {
                currStmp = getNextTimestamp();
            }
        } else {
            sequence = 0L;
        }
 
        lastStmp = currStmp;
 
        return currStmp << TIMESTMP_LEFT //
                | machineId << MACHINE_LEFT //
                | sequence;
    }
 
    private long getNextTimestamp() {
        long mill = getTimestamp();
        while (mill <= lastStmp) {
            mill = getTimestamp();
        }
        return mill;
    }
 
    private long getTimestamp() {
        // per 10ms
        return System.currentTimeMillis() / 10;// 10ms
    }
 
    public static Date parseIdTimestamp(long id) {
        return new Date((id >>> TIMESTMP_LEFT) * 10);
    }
 
    public static String uuid() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }
}

插曲:

在使用mybatisplus时自动插入创建时间之类的操作:

java 复制代码
package com.ssdl.config.autoMatic;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class MybatisHandler implements MetaObjectHandler {
	@Override
	public void insertFill(MetaObject metaObject) {
		//属性名
		this.setFieldValByName("createTime", new Date(), metaObject);
		this.setFieldValByName("updateTime", new Date(), metaObject);
		this.setFieldValByName("isDel", 0, metaObject);
		this.setFieldValByName("createUser", "admin", metaObject);
		this.setFieldValByName("updateUser", "admin", metaObject);
		//this.setFieldValByName("createUser", SecureUtil.getUserId(), metaObject);
        //不维护create_user可以不使用这行代码
	}
 
	@Override
	public void updateFill(MetaObject metaObject) {
		//属性名
		this.setFieldValByName("updateTime", new Date(), metaObject);
		this.setFieldValByName("updateUser", "admin", metaObject);
		//this.setFieldValByName("updateUser", SecureUtil.getUserId(), metaObject);
	}
}
java 复制代码
	@TableId(value = "id",type = IdType.ASSIGN_ID)
    private Long id;

    /**
     * 进行新增或者更新操作时
     * Mybatis自动进行维护时间
     */
    @TableField(fill= FieldFill.INSERT)
    private String createUser;

    @TableField(fill=FieldFill.INSERT)
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;

    @TableField(fill=FieldFill.INSERT_UPDATE)
    @JsonIgnore
    private String updateUser;

    @TableField(fill= INSERT_UPDATE)
    @JsonIgnore
    private Date updateTime;

    @TableLogic
    @TableField(fill= FieldFill.INSERT)
    @JsonIgnore
    private Integer isDel;
相关推荐
IT枫斗者枫哥1 小时前
MyBatis一对多分页:LIMIT 20,为什么凑不齐20个订单?
java·数据库
代码方舟1 小时前
Java数据工程:利用天远全网运营商三要素优化线上实名认证合规体验
java·人工智能
BBmmo1 小时前
我的 Java 学习笔记 · 第 7 篇:泛型与通配符
java
独泪了无痕1 小时前
Hutool之RandomUtil:随机数生成的终极利器
java·后端
花开路口1 小时前
深入理解 Java/Kotlin 协变与逆变
java·kotlin
运行时异常1 小时前
【WMS 仓储系统集成 AI Agent 实战】第 7 讲:Vue3 前端工程化——Token 刷新锁、Markdown 渲染踩坑与权限体系
java
她的男孩1 小时前
开放接口限流从 20 改到 200 还是每分钟 20 次:拆完防重放+幂等+限流,我找到 5 个静默失效的坑
java·后端·架构
天天被压力1 小时前
【Python 量化取数指南 #13】Python 把行情落库:sqlite 一键存,回测随用随取
java·人工智能·python
天天被压力1 小时前
【Python 量化取数指南 #14】Python 清洗行情数据:复权停牌对齐,回测不翻车
java·人工智能·python
独泪了无痕1 小时前
开发利器Hutool之MapUtil的使用
java·后端