Java生成唯一訂單號的幾種方式
前言
訂單號具有唯一標(biāo)識符的作用,下邊將演示自增、隨機、組合的方式,生成高效、安全、唯一的訂單號,以滿足業(yè)務(wù)需求和避免潛在問題。
自增
自增常見的有:純數(shù)字自增、時間+數(shù)字自增、數(shù)據(jù)庫主鍵id自增
純數(shù)字自增
需求:生成8位自增數(shù)字的訂單號,不足8位前綴補0。
實現(xiàn):使用redis的incr函數(shù)完成此需求。
@RestController @RequestMapping("/testOrderCode") public class TestOrderCodeController { @Resource private RedisTemplate<String, Integer> redisTemplate; private static final String TEST_ORDER_CODE_KEY = "test_order_code_key"; @GetMapping("/test") public String test() { //使用incr獲取自增的訂單號 Long increment = redisTemplate.opsForValue().increment(TEST_ORDER_CODE_KEY); //將訂單號不足8位前綴補0,"%08d",%0表示前綴補0,8表示補充8位,d表示數(shù)字類型 String oderCode = String.format("%08d", increment); return oderCode; } } 輸出結(jié)果:00000001
時間+數(shù)字自增
需求:使用年月日(yyMMdd)當(dāng)訂單號前綴,后四位使用當(dāng)日訂單號自增。
實現(xiàn):獲取yyMMdd格式的時間字符串,然后將該字符串作為redis的key使用,并給該key設(shè)置一天的過期時間。后四位數(shù)字自增使用redis的 incr函數(shù)實現(xiàn)。
@RestController @RequestMapping("/testOrderCode") public class TestOrderCodeController { @Resource private RedisTemplate<String, Integer> redisTemplate; private static final String TEST_ORDER_CODE_KEY = "test_order_code_key"; @GetMapping("/test") public String test() { // 定義日期格式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMdd"); //根據(jù)當(dāng)前時間獲取yyMMdd格式的時間字符串 String format = LocalDate.now().format(formatter); //判斷是否存在key,不存在則設(shè)置1天的過期時間 if (Boolean.FALSE.equals(redisTemplate.hasKey(format))) { redisTemplate.expire(format, 1, TimeUnit.DAYS); } //使用incr獲取自增的訂單號 Long increment = redisTemplate.opsForValue().increment(format); //將訂單號不足4位前綴補0,"%04d",%0表示前綴補0,4表示補充4位,d表示數(shù)字類型 String oderCode = String.format("%04d", increment); return format + oderCode; } } 輸出結(jié)果:2412260001
數(shù)據(jù)庫主鍵id自增
需求:生成8位自增數(shù)字的訂單號,不足8位前綴補0。
實現(xiàn):使用數(shù)據(jù)庫自增主鍵實現(xiàn)該需求。先保存訂單到數(shù)據(jù)庫,取訂單id,再將id前綴補0操作后更新到數(shù)據(jù)庫中。
@RestController @RequestMapping("/testOrderCode") public class TestOrderCodeController { @Resource private OrdersMapper orderMapper; @GetMapping("/test") public String test() { //保存訂單,并獲取id OrdersDO ordersDO = new OrdersDO(); orderMapper.insert(ordersDO); Long id = ordersDO.getId(); //將訂單號不足8位前綴補0,"%08d",%0表示前綴補0,8表示補充8位,d表示數(shù)字類型 String oderCode = String.format("%08d", id); //更新訂單號 orderMapper.updateById(ordersDO.setOrderCode(oderCode)); return oderCode; } } 輸出結(jié)果:00000001
隨機
隨機常見的有:隨機數(shù)、UUID、分布式全局唯一id(雪花算法)
隨機數(shù)
需求:生成隨機的訂單號。
實現(xiàn):使用Random生成隨機數(shù)。
import cn.hutool.core.util.RandomUtil; @RestController @RequestMapping("/testOrderCode") public class TestOrderCodeController { @Resource private OrdersMapper orderMapper; @GetMapping("/test") public String test() { // 定義日期格式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMdd"); //根據(jù)當(dāng)前時間獲取yyMMdd格式的時間字符串 String format = LocalDate.now().format(formatter); //生成隨機8位數(shù)字 String random = RandomUtil.randomNumbers(8); //時間+隨機數(shù)組成訂單號 String oderCode = format + random; //判斷生成的訂單號在數(shù)據(jù)庫中是否存在,如果存在則繼續(xù)隨機生成訂單號 while (orderMapper.selectCount(Wrappers.lambdaQuery(OrdersDO.class).eq(OrdersDO::getOrderCode, oderCode)) > 0){ oderCode = format + RandomUtil.randomNumbers(8); } return oderCode; } } 輸出結(jié)果:24122683230048
UUID
需求:生成隨機的訂單號。
實現(xiàn):使用UUID實現(xiàn)該需求。
import java.util.UUID; @RestController @RequestMapping("/testOrderCode") public class TestOrderCodeController { @GetMapping("/test") public String test() { // 生成一個UUID UUID uuid = UUID.randomUUID(); // 將UUID轉(zhuǎn)換為字符串,并移除分隔符 String oderCode = uuid.toString().replace("-", ""); return oderCode; } } 輸出結(jié)果:8a45cd3458b640789ed3c9ef223d090b
分布式全局唯一id(雪花算法)
需求:生成隨機的訂單號。
實現(xiàn):使用分布式全局唯一id(雪花算法)實現(xiàn)該需求。
import cn.hutool.core.lang.Snowflake; @RestController @RequestMapping("/testOrderCode") public class TestOrderCodeController { @GetMapping("/test") public String test() { // 創(chuàng)建一個雪花算法ID生成器實例,通常你需要指定終端ID和數(shù)據(jù)中心ID Snowflake snowflake = new Snowflake(1, 1); String oderCode = snowflake.nextIdStr(); return oderCode; } } 輸出結(jié)果:1872140136729415680
結(jié)語
到此這篇關(guān)于Java生成唯一訂單號的幾種方式的文章就介紹到這了,更多相關(guān)Java生成唯一訂單號內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java SSM實現(xiàn)前后端協(xié)議聯(lián)調(diào)詳解上篇
首先我們已經(jīng)知道,在現(xiàn)在流行的“前后端完全分離”架構(gòu)中,前后端聯(lián)調(diào)是一個不可能避免的問題,這篇文章主要介紹了Java SSM實現(xiàn)前后端協(xié)議聯(lián)調(diào)過程2022-08-08淺談升級Spring Cloud到Finchley后的一點坑
這篇文章主要介紹了淺談升級Spring Cloud到Finchley后的一點坑,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-10-10Triple協(xié)議支持Java異常回傳設(shè)計實現(xiàn)詳解
這篇文章主要為大家介紹了Triple協(xié)議支持Java異?;貍髟O(shè)計實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12Java應(yīng)用程序的CPU使用率飆升原因詳細(xì)分析
這篇文章主要介紹了Java應(yīng)用程序的CPU使用率飆升原因詳細(xì)分析,在 Java 中,我們使用 JVM 進行線程調(diào)度,所以一般來說,線程的調(diào)度有兩種模式:分時調(diào)度和搶占式調(diào)度,線程和進程在阻塞或者等待時,都不會使用 CPU 資源,需要的朋友可以參考下2024-01-01Java?I/O?(Input/Output)文件字節(jié)流舉例詳解
Java的輸入輸出流(IO)是用于與外部設(shè)備(如文件、網(wǎng)絡(luò)連接等)進行數(shù)據(jù)交互的機制,下面這篇文章主要給大家介紹了關(guān)于Java?I/O?(Input/Output)文件字節(jié)流的相關(guān)資料,需要的朋友可以參考下2024-08-08