JAVA自定义规则生成唯一ID

简介: 本文以类型和订单时间为例,SQL方案和Redis方案

自定义规则生成唯一ID(方案一:通过SQL生成)

  • 场景:

    生成物流唯一ID,要求根据创建的订单时间及该订单所属类型,举例:

有一个订单类型为‘普货’,该订单时间为‘2022-07-19 00:00:00’,且该订单为7月底第一订单,则物流ID为:P-2207000001,后面同一类型同一个月的物流ID自增,P-2207000002,规则:类型-时间-指定位数数字字符(type-yyMM-00000...)
  • 实战:
    现有类型:集团外整车(J-)、普货(P-)、零部件(L-)
    规则:类型yyMM六位自增数字
    实现:
    通过SQL直接获取下一个物流唯一ID

image.png

    SELECT (CASE
     WHEN ID_GEN IS NULl AND '零部件'= #{bigType} THEN 'L-'||TO_CHAR(#{orderDate}, 'yyMM')||'000001'
     WHEN ID_GEN IS NULl AND '集团外整车'= #{bigType} THEN 'J-'||TO_CHAR(#{orderDate}, 'yyMM')||'000001'
     WHEN ID_GEN IS NULl AND '普货'= #{bigType} THEN 'P-'||TO_CHAR(#{orderDate}, 'yyMM')||'000001'
     WHEN ID_GEN IS NOT NULl AND '零部件'= #{bigType} THEN 'L-'|| TO_CHAR(#{orderDate}, 'yyMM')|| ID_GEN
     WHEN ID_GEN IS NOT NULl AND '集团外整车'= #{bigType} THEN 'J-' || TO_CHAR(#{orderDate}, 'yyMM')||ID_GEN
     WHEN ID_GEN IS NOT NULl AND '普货'= #{bigType} THEN 'P-'|| TO_CHAR(#{orderDate}, 'yyMM')|| ID_GEN
     ELSE NULL END) AS wayWillNo
  FROM (
      SELECT TO_CHAR(TO_NUMBER(MAX(regexp_replace(WAYBILL_NO, '[^0-9]')))+1, 'fm000000') AS ID_GEN FROM OB_ORDER  WHERE BIG_TYPE=#{bigType} AND TO_CHAR(DTORDER_DATE, 'yyyyMM')=TO_CHAR(#{orderDate}, 'yyyyMM')
    )
</select>  

考虑使用的并发问题,导致取到生成相同的ID,获取ID通过该方法获取,加锁,并预生成部分唯一ID


@Service
public class SeqService {

    private final ReentrantLock lock = new ReentrantLock();

    private static final Map<String,List<String>> waybillMap=new ConcurrentHashMap<>();

    @Autowired
    private OrderMapper orderMapper;
   
   public String  genWaybillNo(String bigType, Date dtOrderDate){
       lock.lock();
       try {
           List<String> list = waybillMap.get(bigType + DateUtils.format(dtOrderDate, "yyMM"));
           if (CollectionUtil.isEmpty(list)) {
               if(list==null){
                   list=new ArrayList<>();
               }
               String waybillNo = orderMapper.genWaybillNo(bigType, dtOrderDate);
               String pre = ("集团外整车".equals(bigType) ? "J-"
                       : ("普货".equals(bigType) ? "P-" : "L-") )+ DateUtils.format(dtOrderDate, "yyMM");
               for (int i = 0; i < 9; i++) {
                   waybillNo = getLastWayBillNo(pre, waybillNo);
                   list.add(waybillNo);
               }
               return waybillNo;
           } else {
               String waybillNo = list.stream().findFirst().get();
               list.remove(waybillNo);
               waybillMap.put(bigType + DateUtils.format(dtOrderDate, "yyMM"), list);
               return waybillNo;
           }
       }finally {
           System.out.println("generate seq unlock");
           lock.unlock();
       }

   }
  //生成下一个
   private static String getLastWayBillNo(String pre,String waybillNo){
       String number = StrUtil.removePrefix(waybillNo, pre);
       if (!StringUtils.isEmpty(number)) {
           int n = number.length(); //取出字符串的长度
           int num = Integer.parseInt(number) + 1; //将该数字加一
           String added = String.valueOf(num);
           n = Math.min(n, added.length());
           //拼接字符串
           return waybillNo.subSequence(0, waybillNo.length() - n) + added;
       } else {
           throw new NumberFormatException();
       }
   }

}

效果:
image.png

自定义规则生成唯一ID(方案二:通过redis生成)

  • 将固定前缀+类型+yyMM作为key,获取ID时,如果为空,拼接生成第一个ID,并set到redis,如果不为空,将取到的值,生成下一个ID并set的redis,生成方法请参考方案一。
  • 或者reids只存数字 incr,前缀自己拼接
目录
相关文章
|
17天前
|
Java
Java 变量命名规则
4月更文挑战第6天
|
1月前
|
Java Spring 容器
【Java】Spring如何扫描自定义的注解?
【Java】Spring如何扫描自定义的注解?
35 0
|
1月前
|
存储 Java 开发者
Java变量命名规则
Java变量命名规则
18 0
|
1月前
|
Web App开发 存储 JavaScript
《手把手教你》系列技巧篇(八)-java+ selenium自动化测试-元素定位大法之By id(详细教程)
【2月更文挑战第17天】本文介绍了Web自动化测试的核心——元素定位。文章首先强调了定位元素的重要性,指出找不到元素则无法进行后续操作。Selenium提供八种定位方法,包括By id、name、class name等。其中,By id是最简单快捷的方式。文章还阐述了自动化测试的步骤:定位元素、操作元素、验证结果和记录测试结果。此外,讨论了如何选择定位方法,推荐优先使用简单稳定的方式,如id,其次考虑其他方法。最后,作者提供了Chrome浏览器的开发者工具作为定位元素的工具,并给出了通过id定位的代码示例。
51 0
|
1天前
|
Java
Java基础知识整理,驼峰规则、流程控制、自增自减
在这一篇文章中我们总结了包括注释、关键字、运算符的Java基础知识点,今天继续来聊一聊命名规则(驼峰)、流程控制、自增自减。
34 3
|
13天前
|
Java
Java配置大揭秘:读取自定义配置文件的绝佳指南
Java配置大揭秘:读取自定义配置文件的绝佳指南
15 0
Java配置大揭秘:读取自定义配置文件的绝佳指南
|
17天前
|
NoSQL Java Redis
Java自定义线程池的使用
Java自定义线程池的使用
|
27天前
Cause: java.sql.SQLIntegrityConstraintViolationException: Column ‘id‘ in field list is ambiguous
Cause: java.sql.SQLIntegrityConstraintViolationException: Column ‘id‘ in field list is ambiguous
17 0
|
1月前
|
Java
java 自定义注解 实现限流
java 自定义注解 实现限流
10 1
|
1月前
|
Java
【Java从入门到精通】Java变量命名规则(1)
【Java从入门到精通】Java变量命名规则(1)
20 0