在使用mybatisplus自带雪花的时候会发现返回的ID是19位的长度,因此在通过swagger页面展示的时候会发现后端返回的和页面展示的ID不一致问题。是因为精度丢失的问题。因此需要更改雪花ID的长度
跟踪进去:
发现是DefaultIdentifierGenerator类实现了IdentifierGenerator并重写了nextId方法,因此需要我们重写nextId方法
- 进行重写:
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 {@Overridepublic Number nextId(Object entity) {return IdGenerator.generateId();}
}
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-04private final static long MACHINE_BIT = 5; // max 31private 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 10msreturn 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时自动插入创建时间之类的操作:
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 {@Overridepublic 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可以不使用这行代码}@Overridepublic void updateFill(MetaObject metaObject) {//属性名this.setFieldValByName("updateTime", new Date(), metaObject);this.setFieldValByName("updateUser", "admin", metaObject);//this.setFieldValByName("updateUser", SecureUtil.getUserId(), metaObject);}
}
@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)@JsonIgnoreprivate String updateUser;@TableField(fill= INSERT_UPDATE)@JsonIgnoreprivate Date updateTime;@TableLogic@TableField(fill= FieldFill.INSERT)@JsonIgnoreprivate Integer isDel;