比雪花短比UUID可读,这个Java业务流水号工具类有3个方法
## 📋 目录 - 一、工具类功能 - 二、所需环境 - 三、方法与调用示例(按需调用) - 四、工具类源码(可直接复制) ## 一、工具类功能 生成「前缀 + 日期(yyyyMMdd) + 递增序列」的短单号,例如 `ORD20261005000001`,比雪花 ID 短、比 UUID 可读,序列按天在进程内递增、入口方法加了同步。 ## 二、所需环境 JDK 17或以上 ## 三、方法与调用示例(按需调用) 🔢 **方法序号**:1 🎯 **方法用途**: - 按系统当天日期出「前缀 + yyyyMMdd + 6 位序列」的业务单号,比雪花 ID 短、比 UUID 可读 - 内部订单号、退款号这类要看日期和先后顺序的场景用它 🧩 **方法定义**:`public static synchronized String next(String prefix)` 🗣️ **入参解释**:`public static synchronized String next(业务前缀)` 📤 **返回值解释**:`String`,形如 `ORD20261013000001` 的单号 💡 **边界口径**: - 序列按天各自计数,某天在本进程首次取号从 1 开始 - 同一天内所有前缀共用一个计数器,换前缀是跳号而不是重新计数 - 序列不足 6 位左补零,涨过 6 位后按实际长度输出,不截断 - 号段只存在内存里,进程重启后当天序列同样从 1 重新开始,只适合单实例、可接受重启重号的内部流水 - 前缀原样拼接,不做长度与字符集校验,但空白前缀被拒绝 🧪 **方法示例**: - 本进程第一次 `next("ORD")` 拿到 `ORD20261013000001` - 紧接着再调一次拿到 `ORD20261013000002`,当天序列往上加 - 换成 `next("PAY")` 拿到 `PAY20261013000003`,同一天所有前缀共用一个计数器 - `next(" ")` 抛 `业务前缀不能为空` --- 🔢 **方法序号**:2 🎯 **方法用途**: - 同样按当天日期取号,补零位数由 `seqLength` 决定 - 单号字段宽度有限、或者想让序列短一点时用这一版 🧩 **方法定义**:`public static synchronized String next(String prefix, int seqLength)` 🗣️ **入参解释**:`public static synchronized String next(业务前缀, 序列位数)` 📤 **返回值解释**:`String`,前缀加日期再加指定位数的序列 💡 **边界口径**: - `seqLength` 只是补零目标,序列涨到比它长时按实际长度输出,不会截断成固定宽度 - `seqLength` 给 1 时没有任何补零,直接是实际序列 - `seqLength` 小于等于 0 抛 `IllegalArgumentException`,消息里带上实际值 - 与单参版共用同一把类锁和同一份号段,两个入口之间也互相递增 🧪 **方法示例**: - `next("REFUND", 3)` 拿到 `REFUND20261013004` - `next("SETTLE", 12)` 拿到 `SETTLE20261013000000000005`,补到 12 位 - `next("MIN", 1)` 拿到 `MIN202610132`,一位都不补 - `next("ORD", 0)` 抛 `序列位数必须大于0,当前为0` - `next("ORD", -3)` 抛 `序列位数必须大于0,当前为-3` --- 🔢 **方法序号**:3 🎯 **方法用途**: - 指定业务日期取号,按历史日期补单、造测试数据时用 - 时钟回拨或跨零点这类场景不想让号段错挂到另一天上,就用这个显式入口 🧩 **方法定义**:`public static synchronized String next(String prefix, LocalDate date, int seqLength)` 🗣️ **入参解释**:`public static synchronized String next(业务前缀, 业务日期, 序列位数)` 📤 **返回值解释**:`String`,前缀加指定日期再加该天的序列 💡 **边界口径**: - 每一天有自己的序列,日期前进后那天首次取号从 1 开始 - 再传回今天会接着当天的序列往上加,既不重发已发出的号,也不被回拨打乱 - 号段只保留最近 7 天,更早的日期被回收后再取号会从 1 重新计 - 取日期、读该天序列、写回在同一个临界区里完成,16000 次并发取号也不重号 - `date` 传 null 抛 `IllegalArgumentException` 🧪 **方法示例**: - `next("SHIP", today, 6)` 拿到 `SHIP20261013000006`,接在当天序列后面 - 日期前进一天首取拿到 `SHIP20261014000001`,那天从零开始 - 再把日期传回今天拿到 `SHIP20261013000007`,当天已用过的号不会被重发 - 8 个线程各取 2000 次去重后拿到 `16000 条`,没有重号 - 序列涨到 16008 之后拿 2 位宽度也是 `TRADE2026101316008`,不截断 - 连续补 10 天的单再回取最早那天,拿到 `ARCH20261004000001`,过期号段被回收后从 1 重计 - `next("ORD", null, 6)` 抛 `业务日期不能为null` ## 四、工具类源码(可直接复制) 📦 评论区留言