您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么使用Java實(shí)現(xiàn)批量生成流水號(hào)”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡單快捷,實(shí)用性強(qiáng),希望這篇“怎么使用Java實(shí)現(xiàn)批量生成流水號(hào)”文章能幫助大家解決問題。
生成流水號(hào),在企業(yè)中可以說是比較常見的需求,尤其是訂單類業(yè)務(wù)。
一般來說,需要保證流水號(hào)的唯一性。
如果沒有長度和字符的限制,那么直接使用UUID生成一個(gè)唯一字符串即可,也可以直接使用數(shù)據(jù)庫表中的主鍵,主鍵就是唯一的。
那么,如果限制了流水號(hào)必須多少位,這種怎么生成呢?
可以采用"前綴+日期+數(shù)字"的方式(ps:此方式是需要用到緩存的)
前綴:為了更好的標(biāo)識(shí)這個(gè)流水號(hào)是屬于哪種類型;
日期:為了防止重復(fù);
數(shù)字:為了表示當(dāng)前的流水所處序號(hào)。
需求:生成一個(gè)17位數(shù)的唯一流水號(hào),“LSH”+yyyyMMdd+6位數(shù)字
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("生成的流水號(hào):"+serialNo);
}
/**
* 生成17位唯一流水號(hào),"LSH"+yyyyMMdd+6位數(shù)字
* 6位數(shù)字,如:000001
* @return
*/
private static String generateSerialNo(){
//定義需要返回的流水號(hào)
String serialNo = null;
//先查詢到今天的日期,格式:"yyyyMMdd"
String todayDate = new SimpleDateFormat("yyyyMMdd")
.format(new Date());
//固定字母前綴 拼接 今天日期,組成新的完整的前綴,也就是緩存的key
String cacheKey = "LSH"+todayDate;
//再通過key查詢緩存有沒有num數(shù)據(jù),緩存操作根據(jù)自身項(xiàng)目封裝工具類
Long codeNum = cacheService.getCache(cacheKey, Long.class);
//如果緩存查詢有值,數(shù)值+1,再賦值給下一個(gè)流水號(hào)
if (null != codeNum) {
codeNum = codeNum + 1L;
} else {
//如果緩存查詢沒值,直接賦值為1
codeNum = 1L;
}
//流水號(hào) = 緩存key + 拼接的數(shù)值 = 前綴 + 日期 + 拼接的數(shù)值
serialNo = getCodeOfSix(cacheKey, codeNum.intValue());
//設(shè)置緩存,調(diào)用此方法,會(huì)自動(dòng)將key所對應(yīng)的value+1,保存時(shí)長:今天剩余的時(shí)間
cacheService.incr(cacheKey, getSeconds());
return serialNo;
}
/**
* 將數(shù)值拼接成對應(yīng)的位數(shù)
* @param prefix 前綴:"LSH"+yyyyMMdd
* @param nowNum 當(dāng)前要生成的數(shù)字
* @return 拼接好的流水號(hào)
*/
public static String getCodeOfSix(String prefix,int nowNum ) {
//需要返回的code
StringBuilder codeSb = new StringBuilder();
//需要拼接的數(shù)字
StringBuilder numSb = new StringBuilder();
//封裝的數(shù)字對象,里面 value 加了 volatile關(guān)鍵字,保證了線程安全
AtomicInteger count = new AtomicInteger(nowNum);
//將數(shù)值補(bǔ)足為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);
//再拼接數(shù)字
codeSb.append(numSb);
return codeSb.toString();
}
/**
* 獲取當(dāng)天結(jié)束還剩余多少秒
* @return
*/
public static int getSeconds(){
//獲取今天當(dāng)前時(shí)間
Calendar curDate = Calendar.getInstance();
//獲取明天凌晨0點(diǎn)的日期
Calendar tommorowDate = new GregorianCalendar(
curDate.get(Calendar.YEAR),
curDate.get(Calendar.MONTH),
curDate.get(Calendar.DATE) + 1,
0, 0, 0);
//返回 明天凌晨0點(diǎn) 和 今天當(dāng)前時(shí)間 的差值(秒數(shù))
return (int)(tommorowDate.getTimeInMillis() - curDate .getTimeInMillis()) / 1000;
}
}
假如今天是2021年4月22日,運(yùn)行項(xiàng)目,生成的第1個(gè)流水號(hào)則為:LSH20210422000001
第2個(gè)流水號(hào)則為:LSH20210422000002,依次類推。
需要注意的是:
如果限制了位數(shù),6位數(shù)字每天最多能生成10w個(gè)流水號(hào),所以,這個(gè)數(shù)字位數(shù)根據(jù)具體業(yè)務(wù)量進(jìn)行調(diào)整。
如果每天的生成數(shù)量量不到1w,那么使用4位數(shù)字即可。
關(guān)于“怎么使用Java實(shí)現(xiàn)批量生成流水號(hào)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。