概述
/**
* 雪花算法生成唯一的有序的序列号
*/
public class SnowflakeUtils {
/**
* 起始的时间戳
*/
private final static long START_STMP = 1567267200000L;//2019-09-01 00:00:00
/**
* 每一部分占用的位数
*/
private final static long SEQUENCE_BIT = 12; //序列号占用的位数
private final static long MACHINE_BIT = 8; //机器标识占用的位数,256个机器
private final static long DATACENTER_BIT = 2;//数据中心占用的位数,4个数据中心
/**
* 每一部分的最大值
*/
private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
/**
* 每一部分向左的位移
*/
private final static long MACHINE_LEFT = SEQUENCE_BIT;
private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
private long datacenterId; //数据中心
private long machineId; //机器标识
private long sequence = 0L; //序列号
private long lastStmp = -1L;//上一次时间戳
public SnowflakeUtils(long datacenterId, long machineId) {
if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
throw new IllegalArgumentException("datacenterId can't be greater than "+MAX_DATACENTER_NUM+" or less than 0");
}
if (machineId > MAX_MACHINE_NUM || machineId < 0) {
throw new IllegalArgumentException("machineId can't be greater than "+MAX_MACHINE_NUM+" or less than 0");
}
this.datacenterId = datacenterId;
this.machineId = machineId;
}
/**
* 产生下一个ID
*
* @return
*/
public synchronized long nextId() {
long currStmp = getNewstmp();
if (currStmp < lastStmp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
}
if (currStmp == lastStmp) {
//相同毫秒内,序列号自增
sequence = (sequence + 1) & MAX_SEQUENCE;
//同一毫秒的序列数已经达到最大
if (sequence == 0L) {
//循环获取多几次,尽可能地避免不可能的可能
for(int i = 0; i< 100; i ++){
currStmp = getNextMill();
if (currStmp != lastStmp){
break;
}
}
}
} else {
//不同毫秒内,序列号置为0
sequence = 0L;
}
lastStmp = currStmp;
return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
| datacenterId << DATACENTER_LEFT //数据中心部分
| machineId << MACHINE_LEFT //机器标识部分
| sequence; //序列号部分
}
private long getNextMill() {
long mill = getNewstmp();
while (mill <= lastStmp) {
mill = getNewstmp();
}
return mill;
}
private long getNewstmp() {
return System.currentTimeMillis();
}
public static long getId() {
SnowflakeUtils idGenerator = new SnowflakeUtils(1, 1);
return idGenerator.nextId();
}
// public static void main(String[] args) {
// SnowflakeUtils snowFlake = new SnowflakeUtils(1, 1);
//
// long start = System.currentTimeMillis();
// System.out.println(snowFlake.nextId());
// System.out.println(System.currentTimeMillis() - start);
// }
}
/**
* mybaits 自定义主键生成器
*/
@Component // 加入到spring容器中
public abstract class MybatisKeyGenerator implements IdentifierGenerator {
@Value("${server.worker-id:1}")
private Integer workerId;
@Value("${server.data-center-id:1}")
private Integer dataCenterId;
@Override
public Number nextId(Object entity) {
//上面的雪花算法
long uid = new SnowflakeUtils(workerId, dataCenterId).nextId();
return uid;
}
}
//使用自定义ID生成器
@Data
@TableName("am_contract")
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "合同信息")
public class AmContract extends BaseEntity<AmContract> {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(type = IdType.ASSIGN_ID) // 使用IdType.ASSIGN_ID
@ApiModelProperty(value = "主键")
private Long id;
/**
* 合同号
*/
@ApiModelProperty(value = "合同号")
private String no;
/**
* 修改者Name
*/
@TableField(exist = false)
@ApiModelProperty(value = "修改者Name")
private String updateByName;
}
最后
以上就是冷静咖啡为你收集整理的Mybatis-plus 自定义ID生成器的全部内容,希望文章能够帮你解决Mybatis-plus 自定义ID生成器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复