1.项目中需要引入mybatisplus核心组件
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mp.version}</version>
</dependency>
2.新建一个类实现IdentifierGenerator,重写id生成策略
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import java.util.UUID;
public class CustomUUIDGenerator implements IdentifierGenerator {
@Override
public boolean assignId(Object idValue) {
return IdentifierGenerator.super.assignId(idValue);
}
//重写雪花id算法
@Override
public Number nextId(Object entity) {
return SequenceUtil.makeId();
}
//重写uuid算法,不过滤-
@Override
public String nextUUID(Object entity) {
return UUID.randomUUID().toString();
}
}
3.在mybatisplus配置文件中注入bean
@Configuration
public class MybatisPlusConfig {
@Bean
public IdentifierGenerator identifierGenerator() {
return new CustomUUIDGenerator();
}
}
4.在实体bean映射类中使用需要在ID字段上加入注解
ASSIGN_UUID即为重写后生成的UUID,原生成的uuid为32位,没有-连接符,id需要使用String类型
@TableId(value = "id", type = IdType.ASSIGN_UUID)
ASSIGN_ID即为重写后生成的雪花id,值为Long类型
@TableId(value = "workspaceid", type = IdType.ASSIGN_ID)
此方法为重写覆盖原生mybatisplus,所以不影响其他地方,id依然会在insert时自动生成.
附:雪花id覆盖Util
import java.util.HashSet;
import java.util.Set;
public class SequenceUtil {
/*** 机 器 Id */
private static long workerId = 0;
/*** 数 据 中 心 */
private static long centerId = 0;
/*** 毫 秒 内 序 列 */
private static long sequence = 0L;
/*** 上 次 Id 生 成 的 时 间 戳 */
private static long lastTimestamp = -1L;
/** 机 器 编 号 所 占 位 数 */
private static final long workerIdBits = 5L;
/** 数 据 标 识 所 占 位 数 */
private static final long centerIdBits = 5L;
/** 开 始 时 间 戳 */
private static final long poc = 1288834974657L;
/** 序 列 在 Id 中 所 占 的 位 数 */
private static final long sequenceBits = 12L;
/** 为 算 法 提 供 可 用 配 置 */
private static final long workerIdShift = sequenceBits;
private static final long maxWorkerId = -1L ^ (-1L << workerIdBits);
private static final long maxCenterId = -1L ^ (-1L << centerIdBits);
private static final long centerIdShift = sequenceBits + workerIdBits;
private static final long timestampLeftShift = sequenceBits + workerIdBits + centerIdBits;
private static final long sequenceMask = -1L ^ (-1L << sequenceBits);
/**
* 获 取 下 一 个 ID ( 该方法都是线程安全的 )
* */
public static synchronized long makeSequence() throws Exception{
long timestamp = timeGen();
// 当 前 时 间 小 于 上 次 Id 生 成 时 间 ,说 明 系 统 时 钟 回 退, 应 会 抛 出 异 常
if (timestamp < lastTimestamp) {
// 服 务 器 时 钟 被 调 整 了, Sequence 生 成 器 停 止 服 务
throw new Exception(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}
// 如 果 是 同 一 时 间 生 成,则 进 行 毫 秒 内 序 列
if (lastTimestamp == timestamp) {
// 每 次 加 +
sequence = (sequence + 1) & sequenceMask;
// 毫 秒 内 序 列 溢 出
if (sequence == 0) {
// 阻塞到下一个毫秒,获取新的时间戳
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
// 暂 存 当 前 时 间 戳 , 为 下 次 使 用 提 供 依 据
lastTimestamp = timestamp;
// 雪 花 算 法 核 心
long currentId = ((timestamp - poc) << timestampLeftShift) | (centerId << centerIdShift) | (workerId << workerIdShift) | sequence;
return currentId;
}
/**
* 获 取 下 一 个 Id
* */
public static long makeId(){
try {
return makeSequence();
}catch (Exception e){
e.printStackTrace();
}
return -1;
}
public static String makeStringId(){
return "" + makeId();
}
/**
* 根 据 一 定 数 量 的 Id
* */
public Set<Long> makeId(int initSize) throws Exception{
Set<Long> ids = new HashSet<>(initSize);
for (long current = 0; current < initSize; current++){
ids.add(makeId());
}
return ids;
}
/**
* 时 间 戳 比 对
* */
protected static long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
/**
* 当 前 系 统 时 间 毫 秒
* */
protected static long timeGen() {
return System.currentTimeMillis();
}
}