|  |  |  | 
|---|
|  |  |  | package com.dy.common.util; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import lombok.extern.slf4j.Slf4j; | 
|---|
|  |  |  | import org.springframework.stereotype.Component; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import java.util.Calendar; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Slf4j | 
|---|
|  |  |  | @Component | 
|---|
|  |  |  | public class IDLongGenerator { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static final int yearLenght = 4 ;//4:年度取四位, 3:年度取三位, 2:年度取两位, 1:年度取一位, 0:年度取0位 | 
|---|
|  |  |  | private static final Object synObj = new Object() ; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static final int yearLength = 4 ;//4:年度取四位, 3:年度取三位, 2:年度取两位, 1:年度取一位, 0:年度取0位 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static int add = 0 ; | 
|---|
|  |  |  | private static final int chengShu = 1000 ;//1000:三位自增量,即一秒钟可产生10000个ID | 
|---|
|  |  |  | 
|---|
|  |  |  | //此ID生成器在各个子系统中难免为同一类数据生成相同的ID,造成数据库插入因主键相同而报错, | 
|---|
|  |  |  | //所以设计此后缀,每个子系统后缀不同 | 
|---|
|  |  |  | private static int suffix = 0 ; | 
|---|
|  |  |  | private static final int noSuffix = 0 ; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | static { | 
|---|
|  |  |  | last = current() ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | *  23 10 28 09 14 40 00000 | 
|---|
|  |  |  | * 长度16的ID,年度取两位,长度18的ID,年度取四位,17位数字超出了javascript的表数范围,javascript会表数不正确 | 
|---|
|  |  |  | *  2023 10 28 09 14 40 00000 | 
|---|
|  |  |  | * 长度19的ID,年度取两位,长度18的ID,年度取四位,17位数字超出了javascript的表数范围,javascript会表数不正确 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public Long generate(){ | 
|---|
|  |  |  | return doGenerate() ; | 
|---|
|  |  |  | synchronized (synObj){ | 
|---|
|  |  |  | //Long id = doGenerate() ; | 
|---|
|  |  |  | //log.info("产生ID = " + id); | 
|---|
|  |  |  | //return id ; | 
|---|
|  |  |  | return doGenerate() ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 设置后缀,不同子系统设置不同的后缀 | 
|---|
|  |  |  | 
|---|
|  |  |  | * @return ID | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static Long generateTodayStartId(){ | 
|---|
|  |  |  | return (currentTodayStart() * chengShu) * 100 + suffix; | 
|---|
|  |  |  | return (currentTodayStart() * chengShu) * 100 + noSuffix; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | 
|---|
|  |  |  | * @return ID | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static Long generateTodayEndId(){ | 
|---|
|  |  |  | return (currentTodayEnd() * chengShu) * 100 + suffix; | 
|---|
|  |  |  | return (currentTodayEnd() * chengShu) * 100 + noSuffix; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | * @return ID | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static Long generateBeforeXDayStartId(int xday){ | 
|---|
|  |  |  | return (beforeXDayStart(xday) * chengShu) * 100 + suffix; | 
|---|
|  |  |  | return (beforeXDayStart(xday) * chengShu) * 100 + noSuffix; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | 
|---|
|  |  |  | * @return ID | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static Long generateBeforeXDayEndId(int xday){ | 
|---|
|  |  |  | return (beforeXDayEnd(xday) * chengShu) * 100 + suffix; | 
|---|
|  |  |  | return (beforeXDayEnd(xday) * chengShu) * 100 + noSuffix; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 执行生成 | 
|---|
|  |  |  | * @return ID | 
|---|
|  |  |  | * @return ID 20231218 104504 06900 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private synchronized Long doGenerate(){ | 
|---|
|  |  |  | private Long doGenerate(){ | 
|---|
|  |  |  | long id ; | 
|---|
|  |  |  | long now = current() ; | 
|---|
|  |  |  | if(now != last){ | 
|---|
|  |  |  | //上次生成ID 与本次生成ID 不在同一秒内 | 
|---|
|  |  |  | last = now ; | 
|---|
|  |  |  | add = 0 ; | 
|---|
|  |  |  | id = last * chengShu + add ++; | 
|---|
|  |  |  | id = last * chengShu + add++; | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | //上次生成ID 与本次生成ID 在同一秒内 | 
|---|
|  |  |  | if(add >= maxAdd){ | 
|---|
|  |  |  | //附加量已经用尽 | 
|---|
|  |  |  | waitNextSecond(last) ;//等到下一秒 | 
|---|
|  |  |  | id = last * chengShu + add ++ ;//返回上一秒生成的ID | 
|---|
|  |  |  | id = last * chengShu + add++ ;//返回上一秒生成的ID | 
|---|
|  |  |  | add = 0 ;//附加量归零,为下一秒准备 | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | //附加量未用尽 | 
|---|
|  |  |  | id = last * chengShu + add ++ ; | 
|---|
|  |  |  | id = last * chengShu + add++ ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return (id * 100) + suffix ; | 
|---|
|  |  |  | 
|---|
|  |  |  | * @return 处理后的年度 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private static int dealYear(int year){ | 
|---|
|  |  |  | if(yearLenght == 0){ | 
|---|
|  |  |  | if(yearLength == 0){ | 
|---|
|  |  |  | return 0 ; | 
|---|
|  |  |  | }else if(yearLenght == 1){ | 
|---|
|  |  |  | }else if(yearLength == 1){ | 
|---|
|  |  |  | return year % 10 ; | 
|---|
|  |  |  | }else if(yearLenght == 2){ | 
|---|
|  |  |  | }else if(yearLength == 2){ | 
|---|
|  |  |  | return year % 100 ; | 
|---|
|  |  |  | }else if(yearLenght == 3){ | 
|---|
|  |  |  | }else if(yearLength == 3){ | 
|---|
|  |  |  | return year % 1000 ; | 
|---|
|  |  |  | }else if(yearLenght == 4){ | 
|---|
|  |  |  | }else if(yearLength == 4){ | 
|---|
|  |  |  | return year ; | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | return year ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //   public static void main(String[] args){ | 
|---|
|  |  |  | //      Calendar cal = Calendar.getInstance(); | 
|---|
|  |  |  | //      System.out.println(cal.get(Calendar.MONTH) + 1) ; | 
|---|
|  |  |  | // | 
|---|
|  |  |  | //      IDLongGenerator o = new IDLongGenerator() ; | 
|---|
|  |  |  | //      int total = 800 ; | 
|---|
|  |  |  | //      long start = System.currentTimeMillis() ; | 
|---|
|  |  |  | //      int total = 1 ; | 
|---|
|  |  |  | //      for(int i = 0 ; i < total ; i++){ | 
|---|
|  |  |  | //         System.out.println(o.generate()) ; | 
|---|
|  |  |  | //      } | 
|---|
|  |  |  | //      long start = System.currentTimeMillis() ; | 
|---|
|  |  |  | //      long end = System.currentTimeMillis() ; | 
|---|
|  |  |  | //      System.out.println("产生" + total + "ID用时" + (end - start) + "毫秒"); | 
|---|
|  |  |  | // | 
|---|