sunny123456

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  1796 随笔 :: 22 文章 :: 24 评论 :: 226万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

java 生成流水号 java流水号生成器 转载
原文链接:https://blog.51cto.com/u_16099315/6331544

    生成流水线单号格式:业务码+yyyyMMdd+数字

例如: LSH2022102700001

业务码+秒级时间戳+((userId+随机数)加密)

JAVA生成编号工具类

生成流水号(格式:业务码+时间+当天自增号)

业务码+日级时间戳+(查询数据库自增)

java自动生成流水号(格式:业务码+时间+当天自增号)

业务码+日级时间戳+(查询缓存自增)

key为(业务码+日级时间戳)

过期时间为当天的剩余时间

 如何使用Java实现批量生成流水号 附详细实例代码

业务码+日级时间戳+(查询缓存自增) 实现代码

import org.redisson.api.RLock;

import org.redisson.api.RedissonClient;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;

import java.util.Calendar;

import java.util.Date;

import java.util.GregorianCalendar;

import java.util.concurrent.TimeUnit;




/**







生成流水线单号格式:业务码+yyyyMMdd+数字








例如: LSH2022102700001









@author lyn

/

@Component

public class SerialNoUtils {

/*





订单类别头

*/





public static final String ORDER_CODE = "DD-";

/**





退货类别头

*/





public static final String RETURN_ORDER = "THD-";

/**





退款类别头

*/





public static final String REFUND_ORDER = "TKD-";

/**





序号长度

*/

public static final int SORT_LENGTH = 6;





@Autowired

private StringRedisTemplate redisTemplate;




@Autowired

private RedissonClient redissonClient;




/**





生成17位唯一流水号,"LSH"+yyyyMMdd+6位数字


6位数字,如:000001




@param bizCode 业务码


@return

*/

public String generateSerialNo(String bizCode) {

//定义需要返回的流水号

String serialNo = null;

//先查询到今天的日期,格式:"yyyyMMdd"

String todayDate = new SimpleDateFormat("yyyyMMdd")

.format(new Date());

//固定字母前缀 拼接 今天日期,组成新的完整的前缀,也就是缓存的key

String cacheKey = bizCode + todayDate;

RLock lock = redissonClient.getLock("SerialNoLock" + cacheKey);

//通过key查询缓存有没有num数据,没有赋初始值并设置过期时间

try {

lock.lock();

if (Boolean.FALSE.equals(redisTemplate.hasKey(cacheKey))) {

redisTemplate.opsForValue().set(cacheKey, "0", getSeconds(), TimeUnit.SECONDS);

}

//再通过key查询缓存有没有num数据,缓存操作根据自身项目封装工具类

String value = redisTemplate.opsForValue().get(cacheKey);

Long codeNum = null;

//如果缓存查询有值,数值+1,再赋值给下一个流水号

if (null != value) {

codeNum = Long.parseLong(value) + 1L;

} else {

//如果缓存查询没值,直接赋值为1

codeNum = 1L;

}

//流水号 = 缓存key + 拼接的数值 = 前缀 + 日期 + 拼接的数值

serialNo = getCodeOfSix(cacheKey, codeNum.intValue());

//设置缓存,调用此方法,会自动将key所对应的value+1,保存时长:今天剩余的时间

redisTemplate.opsForValue().increment(cacheKey, 1);

} finally {

lock.unlock();

}

return serialNo;

}





/**







将数值拼接成对应的位数










@param prefix 前缀:"LSH"+yyyyMMdd








@param nowNum 当前要生成的数字








@return 拼接好的流水号

*/

private String getCodeOfSix(String prefix, int nowNum) {




//需要拼接的数字

StringBuilder numSb = new StringBuilder(prefix);

//补零

int num = SORT_LENGTH - String.valueOf(nowNum).length();

for (int i = 0; i < num; i++) {

numSb.append("0");

}

numSb.append(nowNum);

return numSb.toString();

}

/**








获取当天结束还剩余多少秒







@return

*/

private static int getSeconds() {

//获取今天当前时间

Calendar curDate = Calendar.getInstance();

//获取明天凌晨0点的日期

Calendar tomorrowDate = new GregorianCalendar(

curDate.get(Calendar.YEAR),

curDate.get(Calendar.MONTH),

curDate.get(Calendar.DATE) + 1,

0, 0, 0);

//返回 明天凌晨0点 和 今天当前时间 的差值(秒数)+1000(防止提前失效)

return (int) (tomorrowDate.getTimeInMillis() - curDate.getTimeInMillis()) / 1000 + 1000;

}

}



posted on   sunny123456  阅读(1234)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2021-08-01 $(document).ready和window.onload区别
2021-08-01 为什么script标签一般放在body下面
2021-08-01 idea添加jar和移除jar包的三种方式
2021-08-01 HTML转义字符大全(转)
2021-08-01 C#中 以固定长度 取字符串中的数据
2021-08-01 Oracle的substr函数简单用法和 C#中一样
2021-08-01 ORA-22835:缓冲区对于CLOB到CHAR转换而言太小
点击右上角即可分享
微信分享提示