新增主键ID生成器

master
星期八 4 years ago
parent 0d136a13c3
commit 8c2246cc85
  1. 14
      panda-jdbc/src/main/java/org/panda/jdbc/id/IdGenerate.java
  2. 138
      panda-jdbc/src/main/java/org/panda/jdbc/id/SnowflakeIdGenerate.java
  3. 14
      panda-jdbc/src/main/java/org/panda/jdbc/id/UUIdGenerate.java

@ -0,0 +1,14 @@
package org.panda.jdbc.id;
/**
* 数据库主键ID生成器
* @author qi
*/
public interface IdGenerate<T> {
/**
*
* @return 主键ID
*/
T nextId();
}

@ -0,0 +1,138 @@
package org.panda.jdbc.id;
/**
* @Description 雪花主键ID生成
* @Author qi
**/
public class SnowflakeIdGenerate implements IdGenerate<Long> {
/**
* 开始时间戳
*/
private final long twepoch = 1420041600000L;
/**
* 机器id所占的位数
*/
private final long workerIdBits = 5L;
/**
* 数据标识id所占的位数
*/
private final long dataCenterIdBits = 5L;
/**
* 支持的最大机器ID,结果是31(位移算法可以很快计算出二进制所能表示的最大十进制数)
*/
private final long maxWorkerId = -1L^(-1L<<workerIdBits);
/**
* 支持的最大数据标识DI,结果是31
*/
private final long maxDataCenterId = -1L^(-1L<<dataCenterIdBits);
/**
* 序列在id中咱的位数
*/
private final long sequenceBits = 12L;
/**
* 机器ID向左位移12位
*/
private final long workerIdShift = sequenceBits;
/**
* 数据标识ID向左位移17位(12+5)
*/
private final long dataCenterIdShift = sequenceBits+workerIdBits;
/**
* 时间戳向左位移22位(12+5+5)
*/
private final long timestampLeftShift =sequenceBits+workerIdBits+dataCenterIdShift;
/**
* 生成序列的掩码,这里为4095
*/
private final long sequenceMask = -1L^(-1L<<sequenceBits);
/**
* 工作机器ID(0-31)
*/
private long workerId;
/**
* 数据中心ID(0-31)
*/
private long dataCenterId;
/**
* 毫秒内序列0-4095
*/
private long sequence = 0L;
/**
* 上次生成ID的时间戳
*/
private long lastTimeStamp = -1L;
/**
* 构造方法
* @param workerId 机器ID
* @param dataCenterId 数据中心ID
*/
public SnowflakeIdGenerate(long workerId, long dataCenterId) {
if (workerId>maxWorkerId||workerId<0){
throw new IllegalArgumentException();
}
if (dataCenterId>maxDataCenterId||dataCenterId<0){
throw new IllegalArgumentException();
}
this.workerId = workerId;
this.dataCenterId = dataCenterId;
}
@Override
public synchronized Long nextId() {
long timestamp = timeGen();
if (timestamp<lastTimeStamp){
throw new RuntimeException(
String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimeStamp - timestamp));
}
if (lastTimeStamp == timestamp){
sequence = (sequence+1)&sequenceMask;
if (sequenceMask == 0){
timestamp = tilNextMillis(lastTimeStamp);
}
}else {
sequence = 0L;
}
//上次生成ID的时间戳
lastTimeStamp = timestamp;
return ((timestamp-twepoch)<<timestampLeftShift)
|(dataCenterId<<dataCenterIdShift)
|(workerId<<workerIdShift)
|sequence;
}
/**
* 阻塞到下一个毫秒,知道获取新的时间戳
* @param lastTimestamp
* @return
*/
private long tilNextMillis(long lastTimestamp){
long timestamp = timeGen();
while (timestamp<=lastTimestamp){
timestamp = timeGen();
}
return timestamp;
}
/**
* 获取当前时间戳
* @return
*/
private long timeGen(){
return System.currentTimeMillis();
}
}

@ -0,0 +1,14 @@
package org.panda.jdbc.id;
import java.util.UUID;
/**
* @Description uuid主键生成
* @Author qi
**/
public class UUIdGenerate implements IdGenerate<String> {
@Override
public String nextId() {
return UUID.randomUUID().toString();
}
}
Loading…
Cancel
Save