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;
相关推荐
严文文-Chris20 分钟前
【设计模式-享元】
android·java·设计模式
Flying_Fish_roe37 分钟前
浏览器的内存回收机制&监控内存泄漏
java·前端·ecmascript·es6
c#上位机1 小时前
C#事件的用法
java·javascript·c#
【D'accumulation】1 小时前
典型的MVC设计模式:使用JSP和JavaBean相结合的方式来动态生成网页内容典型的MVC设计模式
java·设计模式·mvc
试行2 小时前
Android实现自定义下拉列表绑定数据
android·java
茜茜西西CeCe2 小时前
移动技术开发:简单计算器界面
java·gitee·安卓·android-studio·移动技术开发·原生安卓开发
救救孩子把2 小时前
Java基础之IO流
java·开发语言
小菜yh2 小时前
关于Redis
java·数据库·spring boot·redis·spring·缓存
宇卿.2 小时前
Java键盘输入语句
java·开发语言