MyBatis-Plus 内置雪花算法主键重复问题
阅读本文大概需要 2.8 分钟。
来自:blog.csdn.net/wagnteng/article/details/117064242
问题分析
-
服务器时间 -
workId(机器 ID 部分) -
datacenterId(数据标识 ID 部分)。
public Sequence() {
this.datacenterId = getDatacenterId(maxDatacenterId);
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
}
//获取workerId
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
StringBuilder mpid = new StringBuilder();
mpid.append(datacenterId);
//代表正在运行的Java虚拟机的名称。
String name = ManagementFactory.getRuntimeMXBean().getName();
if (StringUtils.isNotEmpty(name)) {
/*
* GET jvmPid
*/
mpid.append(name.split(StringPool.AT)[0]);
}
/*
* MAC + PID 的 hashcode 获取16个低位
*/
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
}
问题解决
# 设置随机
mybatis-plus.global-config.worker-id: ${random.int}
# 设置随机
mybatis-plus.global-config.worker-id: ${random.int(1,31)}
com.baomidou.mybatisplus.core.toolkit.IdWorker
这个核心类,获取id的核心方法是com.baomidou.mybatisplus.core.toolkit.IdWorker#getId
,那我们就在这里加一个断点看下
public class IdWorker {
/**
* 主机和进程的机器码
*/
private static Sequence WORKER = new Sequence();
//获取id
public static long getId() {
return WORKER.nextId();
}
public static String getIdStr() {
return String.valueOf(WORKER.nextId());
}
/**
* <p>
* 有参构造器
* </p>
*
* @param workerId 工作机器 ID
* @param datacenterId 序列号
*/
public static void initSequence(long workerId, long datacenterId) {
WORKER = new Sequence(workerId, datacenterId);
}
/**
* <p>
* 使用ThreadLocalRandom获取UUID获取更优的效果 去掉"-"
* </p>
*/
public static String get32UUID() {
ThreadLocalRandom random = ThreadLocalRandom.current();
return new UUID(random.nextLong(), random.nextLong()).toString().replace(StringPool.DASH, StringPool.EMPTY);
}
}
com.baomidou.mybatisplus.core.MybatisConfiguration#init
方法来初始化配置信息,我们看下代码
public void init(GlobalConfig globalConfig) {
// 初始化 Sequence
//这里需要同时设置workerId和datacenterId
if (null != globalConfig.getWorkerId()
&& null != globalConfig.getDatacenterId()) {
IdWorker.initSequence(globalConfig.getWorkerId(), globalConfig.getDatacenterId());
}
// 打印 Banner
if (globalConfig.isBanner()) {
System.out.println(" _ _ |_ _ _|_. ___ _ | _ ");
System.out.println("| | |\\/|_)(_| | |_\\ |_)||_|_\\ ");
System.out.println(" / | ");
System.out.println(" "+MybatisPlusVersion.getVersion()+" ");
}
}
# 设置随机
mybatis-plus.global-config.worker-id: ${random.int(1,31)}
mybatis-plus.global-config.datacenter-id: ${random.int(1,31)}
推荐阅读:
SpringBoot 运行内存及内存参数设置:助力高效应用部署与优化
互联网初中高级大厂面试题(9个G) 内容包含Java基础、JavaWeb、MySQL性能优化、JVM、锁、百万并发、消息队列、高性能缓存、反射、Spring全家桶原理、微服务、Zookeeper......等技术栈!
⬇戳阅读原文领取! 朕已阅