如何根据日期+数字生成流水号
生成流水号,在企业中可以说是比较常见的需求,尤其是订单类业务。
一般来说,需要保证流水号的唯一性。
如果没有长度和字符的限制,那么直接使用UUID生成一个唯一字符串即可,具体可参考我的这篇文章:java生成类似token的唯一随机字符串
也可以直接使用数据库表中的主键,主键就是唯一的。
那么,如果限制了流水号必须多少位,这种怎么生成呢?
可以采用"前缀+日期+数字"的方式(ps:此方式是需要用到缓存的)
前缀:为了更好的标识这个流水号是属于哪种类型;
日期:为了防止重复;
数字:为了表示当前的流水所处序号。
需求:生成一个17位数的唯一流水号,“LSH”+yyyyMMdd+6位数字
下面,就是具体的代码实现,具体内容可参考注释
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.concurrent.atomic.AtomicInteger;public class SerialNoTest {public static void main(String[] args) {String serialNo = generateSerialNo();System.out.println("生成的流水号:"+serialNo);}/*** 生成17位唯一流水号,"LSH"+yyyyMMdd+6位数字* 6位数字,如:000001* @return*/private static String generateSerialNo(){//定义需要返回的流水号String serialNo = null;//先查询到今天的日期,格式:"yyyyMMdd"String todayDate = new SimpleDateFormat("yyyyMMdd").format(new Date());//固定字母前缀 拼接 今天日期,组成新的完整的前缀,也就是缓存的keyString cacheKey = "LSH"+todayDate;//再通过key查询缓存有没有num数据,缓存操作根据自身项目封装工具类Long codeNum = cacheService.getCache(cacheKey, Long.class);//如果缓存查询有值,数值+1,再赋值给下一个流水号if (null != codeNum) {codeNum = codeNum + 1L;} else {//如果缓存查询没值,直接赋值为1codeNum = 1L;}//流水号 = 缓存key + 拼接的数值 = 前缀 + 日期 + 拼接的数值serialNo = getCodeOfSix(cacheKey, codeNum.intValue());//设置缓存,调用此方法,会自动将key所对应的value+1,保存时长:今天剩余的时间cacheService.incr(cacheKey, getSeconds());return serialNo;}/*** 将数值拼接成对应的位数* @param prefix 前缀:"LSH"+yyyyMMdd* @param nowNum 当前要生成的数字* @return 拼接好的流水号*/public static String getCodeOfSix(String prefix,int nowNum ) {//需要返回的codeStringBuilder codeSb = new StringBuilder();//需要拼接的数字StringBuilder numSb = new StringBuilder();//封装的数字对象,里面 value 加了 volatile关键字,保证了线程安全AtomicInteger count = new AtomicInteger(nowNum);//将数值补足为6位字符串if (count.get() < 10) {numSb.append("00000").append(count.get());} else if(count.get() < 100){numSb.append("0000").append(count.get());}else if(count.get() < 1000){numSb.append("000").append(count.get());}else if(count.get() < 10000){numSb.append("00").append(count.get());}else if(count.get() < 100000){numSb.append("0").append(count.get());} else if (count.get() >= 100000) {numSb.append(count.get());}//先拼接前缀codeSb.append(prefix);//再拼接数字codeSb.append(numSb);return codeSb.toString();}/*** 获取当天结束还剩余多少秒* @return*/public static int getSeconds(){//获取今天当前时间Calendar curDate = Calendar.getInstance();//获取明天凌晨0点的日期Calendar tommorowDate = new GregorianCalendar(curDate.get(Calendar.YEAR),curDate.get(Calendar.MONTH), curDate.get(Calendar.DATE) + 1,0, 0, 0);//返回 明天凌晨0点 和 今天当前时间 的差值(秒数) return (int)(tommorowDate.getTimeInMillis() - curDate .getTimeInMillis()) / 1000;}
}
假如今天是2021年4月22日,运行项目,生成的第1个流水号则为:LSH20210422000001
第2个流水号则为:LSH20210422000002,依次类推。
需要注意的是:
如果限制了位数,6位数字每天最多能生成10w个流水号,所以,这个数字位数根据具体业务量进行调整。
如果每天的生成数量量不到1w,那么使用4位数字即可。
如何根据日期+数字生成流水号相关推荐
- java oracle 流水号_Oracle生成流水号函数
一.参考 1:日期范围上 smalldatetime的有效时间范围1900/1/1~2079/6/6 datetime的有效时间范围1753/1/1~9999/12/31 2:精准度上 smallda ...
- sql server 按照日期自动生成单据编号的函数
一.sql server 按照日期自动生成单据编号的函数,格式为##08080001,##表示打头的单据字符,然后是年月和流水编号. 二.传入的参数为单据的打头字符和生成单据的日期 三.一般的调用格式 ...
- 根据时间戳生成编号_使用雪花算法生成流水号!
前言"在分布式系统中常见的问题就是如何生成流水号,一般情况下会有专门的流水号系统,不过在开发过程中或者开发早期不一定会有专门流水号系统,在这里介绍下我所使用的流水号生成器--雪花算法&quo ...
- 用SerialNumber生成流水号
在很多程序的应用中,有许多的地方会用到流水号,我写了个专门用来生成流水号的类 使用: SerialNumber sn=new SerialNumber(); sn.getSerialNum(table ...
- 使用redis生成流水号
转载请标明出处: 使用redis生成流水号_付付讶的博客-CSDN博客 本文出自使用redis生成流水号_付付讶的博客-CSDN博客 公司需求:生成14位时间+redis流水3位+"-&qu ...
- Oracle 生成流水号
辅助表(RUL_SEQUENCE): 表中数据如图: 辅助存储过程(Proc_GetSeqence): CREATE OR REPLACE PROCEDURE Proc_GetSeqence(SeqC ...
- 帮我用Java写一个生成流水号的方法
我可以给你提供一个使用Java来生成流水号的简单方法: 使用java.util.UUID类来生成一个唯一的字符串: 使用java.time.LocalDateTime类来获取当前的日期和时间: 将上述 ...
- mysql 生成流水号 存储过程 订单编号
用存储过程生成流水号是很常用的,这里以生成订单编号的流水号作为示例.(新的一天的流水号从1开始,如:今天的订单编号是CD2013010900014,下一个订单编号将是CD2013010900015:明 ...
- sql自动生成流水号
创建表 CREATE TABLE CreateSerialNo (CreateSerialNoId INT PRIMARY KEY IDENTITY(1,1),TableName VARCHAR(60 ...
- P1132 数字生成游戏
题目描述 小明完成了这样一个数字生成游戏,对于一个不包含00的数字ss来说,有以下33种生成新的数的规则: 将ss的任意两位对换生成新的数字,例如143143可以生成314,413,134314,41 ...
最新文章
- 这张程序员情绪波动图,未免太真实了! | 每日趣闻
- C#中的Params、ref、out的区别
- 全球及中国人寿保险产业盈利能力与十四五营销策略咨询报告2022版
- android底层rsa加密,android 下RSA加密解密
- MSU发布2018年视频压缩评比报告
- threejs坐标转换
- android-pageviewer实现linearlayout的切换
- mysql 字段 浮点_MySQL浮点数据字段不接受每个浮点数?如何解决这个问题?
- 判断服务器芯片还是民用芯片,抢鲜看,Xeon E3-1230对比I7 2600评测
- 论文阅读笔记(五)——FD-MOBILENET
- Java试题库(含答案)
- K3 Cloud 常用数据表整理
- HTML制作用户登录界面
- 网站推广优化教程100条(完整版)
- 校园锐捷路由器使用指南
- 一小心删除了系统文件NTDETECT.COM怎么办
- python 开放端口探测工具
- 基于Qt ffmpeg opengl开发跨平台安卓实时投屏软件
- vagrant启动失败解决
- 可能是最全的人工智能入门书单(附PDF链接)