parent
0d136a13c3
commit
8c2246cc85
3 changed files with 166 additions and 0 deletions
@ -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…
Reference in new issue