Bootstrap

JAVA 生成唯一订单号的几种方式

前言

订单号具有唯一标识符的作用,下边将演示自增、随机、组合的方式,生成高效、安全、唯一的订单号,以满足业务需求和避免潜在问题。

自增

自增常见的有:纯数字自增时间+数字自增数据库主键id自增

纯数字自增

需求:生成8位自增数字的订单号,不足8位前缀补0。
实现:使用redis的incr函数完成此需求。

@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表示数字类型
        String oderCode = String.format("%08d", increment);
        return oderCode;
    }
}
输出结果:00000001

时间+数字自增

需求:使用年月日(yyMMdd)当订单号前缀,后四位使用当日订单号自增。
实现:获取yyMMdd格式的时间字符串,然后将该字符串作为redis的key使用,并给该key设置一天的过期时间。后四位数字自增使用redis的 incr函数实现。

@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");
        //根据当前时间获取yyMMdd格式的时间字符串
        String format = LocalDate.now().format(formatter);
        //判断是否存在key,不存在则设置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表示数字类型
        String oderCode = String.format("%04d", increment);
        return format + oderCode;
    }
}
输出结果:2412260001

数据库主键id自增

需求:生成8位自增数字的订单号,不足8位前缀补0。
实现:使用数据库自增主键实现该需求。先保存订单到数据库,取订单id,再将id前缀补0操作后更新到数据库中。

@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表示数字类型
        String oderCode = String.format("%08d", id);
        //更新订单号
        orderMapper.updateById(ordersDO.setOrderCode(oderCode));
        return oderCode;
    }
}
输出结果:00000001

随机

随机常见的有:随机数UUID分布式全局唯一id(雪花算法)

随机数

需求:生成随机的订单号。
实现:使用Random生成随机数。

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");
        //根据当前时间获取yyMMdd格式的时间字符串
        String format = LocalDate.now().format(formatter);
        //生成随机8位数字
        String random = RandomUtil.randomNumbers(8);
        //时间+随机数组成订单号
        String oderCode = format + random;
        //判断生成的订单号在数据库中是否存在,如果存在则继续随机生成订单号
        while (orderMapper.selectCount(Wrappers.lambdaQuery(OrdersDO.class).eq(OrdersDO::getOrderCode, oderCode)) > 0){
            oderCode = format + RandomUtil.randomNumbers(8);
        }
        return oderCode;
    }
}
输出结果:24122683230048

UUID

需求:生成随机的订单号。
实现:使用UUID实现该需求。

import java.util.UUID;

@RestController
@RequestMapping("/testOrderCode")
public class TestOrderCodeController {

    @GetMapping("/test")
    public String test() {
        // 生成一个UUID
        UUID uuid = UUID.randomUUID();
        // 将UUID转换为字符串,并移除分隔符
        String oderCode = uuid.toString().replace("-", "");
        return oderCode;
    }
}
输出结果:8a45cd3458b640789ed3c9ef223d090b

分布式全局唯一id(雪花算法)

需求:生成随机的订单号。
实现:使用分布式全局唯一id(雪花算法)实现该需求。

import cn.hutool.core.lang.Snowflake;

@RestController
@RequestMapping("/testOrderCode")
public class TestOrderCodeController {

    @GetMapping("/test")
    public String test() {
        // 创建一个雪花算法ID生成器实例,通常你需要指定终端ID和数据中心ID
        Snowflake snowflake = new Snowflake(1, 1);
        String oderCode = snowflake.nextIdStr();
        return oderCode;
    }
}
输出结果:1872140136729415680

结语

如有问题,还望告知。不胜感激!

这篇文章对你有帮助的话,动动你可爱的小手指,点个赞再走吧。非常感谢!

;