参照 https://blog.youkuaiyun.com/weixin_42851487/article/details/82842055
@Autowired private RedisService redisService;
测试实例
redisService.getSerialBizId("CG","yyyyMMddHH",5)
/**
* 生成单据号
* @param prefixBizCode
* @param timeFormatter
* @param numLength
* @return
*/
public String getSerialBizId(String prefixBizCode, String timeFormatter, int numLength) {
String serialNumLength="";
for(int i=0; i<numLength; i++){
serialNumLength+="0";
}
if(StringUtil.isEmpty(timeFormatter)){
timeFormatter="yyyyMMddHHmmss"; //yyyyMMddHHmmss
}
//默认序列号位数
if(StringUtil.isEmpty(serialNumLength)){//默认
serialNumLength="000000";
}
SimpleDateFormat sdf=new SimpleDateFormat(timeFormatter);
Date date=new Date();
String formatDate=sdf.format(date);
String key= prefixBizCode+formatDate;
Long incr = getIncr(key, getCurrent2TodayEndMillisTime());
if(incr==0) {
incr = getIncr(key, getCurrent2TodayEndMillisTime());//从000001开始
}
DecimalFormat df=new DecimalFormat(serialNumLength);//流水号位数
return prefixBizCode+formatDate+df.format(incr);
}
/**
* 根据key获取redis值
* @param key
* @param liveTime
* @return
*/
public Long getIncr(String key, long liveTime) {
RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
Long increment = entityIdCounter.getAndIncrement();
if ((null == increment || increment.longValue() == 0) && liveTime > 0) {//初始设置过期时间
entityIdCounter.expire(liveTime, TimeUnit.MILLISECONDS);//单位毫秒
}
return increment;
}
/**
* 系统日期的毫秒数
* @return
*/
public Long getCurrent2TodayEndMillisTime() {
Calendar todayEnd = Calendar.getInstance();
// Calendar.HOUR 12小时制
// HOUR_OF_DAY 24小时制
todayEnd.set(Calendar.HOUR_OF_DAY, 23);
todayEnd.set(Calendar.MINUTE, 59);
todayEnd.set(Calendar.SECOND, 59);
todayEnd.set(Calendar.MILLISECOND, 999);
return todayEnd.getTimeInMillis()-new Date().getTime();
}
本文介绍了一种使用Redis和Java生成具有时间戳和序列号的唯一单据编号的方法。通过结合业务前缀、时间格式和固定长度的序列号,确保了在高并发场景下单据编号的唯一性和有序性。
1713

被折叠的 条评论
为什么被折叠?



