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