java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot订单号生成系统

在SpringBoot中实现一个订单号生成系统的示例代码

作者:一只爱撸猫的程序猿

在Spring Boot中设计一个订单号生成系统,主要考虑到生成的订单号需要满足的几个要求:唯一性、可扩展性、以及可能的业务相关性,本文给大家介绍了几种常见的解决方案及相应的示例代码,需要的朋友可以参考下

1. UUID

最简单的方法是使用UUID生成唯一的订单号。UUID(Universally Unique Identifier)是一种广泛使用的标识符,由128位组成,通常以32个十六进制数字表示,分为五组,形式为8-4-4-4-12的字符串,例如123e4567-e89b-12d3-a456-426614174000。UUID全球唯一,实现简单,但缺点是UUID较长,不易记忆和存储。

实例代码

Java中生成UUID的示例代码如下:

import java.util.UUID;

public class UUIDGenerator {

    public static String generateUUID() {
        // 生成一个UUID
        UUID uuid = UUID.randomUUID();
        
        // 将UUID转换为字符串
        String uuidAsString = uuid.toString();
        
        // 返回UUID字符串
        return uuidAsString;
    }

    public static void main(String[] args) {
        String uuid = generateUUID();
        System.out.println("Generated UUID: " + uuid);
    }
}

2. 数据库序列或自增ID

利用数据库的序列(如PostgreSQL的SEQUENCE)或自增ID(如MySQL的AUTO_INCREMENT)生成唯一的订单号。数据库序列或自增ID是一种常见的生成唯一标识符的方法,特别是在单体应用或非分布式系统中。这种方法依赖于数据库的内置机制来保证每次插入新记录时自动产生一个唯一的标识符,缺点是难以在分布式环境中维护唯一性。

// 假设使用JPA
@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    // 其他属性
}

数据库序列(如PostgreSQL的SEQUENCE)

CREATE SEQUENCE order_id_seq START WITH 1 INCREMENT BY 1;

CREATE TABLE orders (
    order_id bigint NOT NULL DEFAULT nextval('order_id_seq'),
    order_data text
);

自增ID(如MySQL的AUTO_INCREMENT)

CREATE TABLE orders (
    order_id INT AUTO_INCREMENT,
    order_data TEXT,
    PRIMARY KEY (order_id)
);

3. 时间戳+随机数/序列

结合时间戳和随机数(或自定义序列)生成订单号,以保证唯一性和可读性。可以通过添加业务相关的前缀来增强业务相关性。

实例代码

以下是一个简单的Java示例,展示了如何结合时间戳、随机数和业务前缀生成订单号:

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ThreadLocalRandom;

public class OrderNumberGenerator {

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
    private static final int RANDOM_NUM_BOUND = 10000; // 定义随机数范围

    public static String generateOrderNumber(String prefix) {
        // 生成时间戳部分
        String timestamp = dateFormat.format(new Date());
        
        // 生成随机数部分
        int randomNumber = ThreadLocalRandom.current().nextInt(RANDOM_NUM_BOUND);
        
        // 组合成订单号
        return prefix + timestamp + String.format("%04d", randomNumber);
    }

    public static void main(String[] args) {
        // 示例:生成订单号,假设业务前缀为"ORD"
        String orderNumber = generateOrderNumber("ORD");
        System.out.println("Generated Order Number: " + orderNumber);
    }
}

4. 分布式唯一ID生成方案

在分布式系统中,可以使用像Twitter的Snowflake算法生成唯一的ID。Snowflake算法可以生成一个64位的长整数,其中包含时间戳、数据中心ID、机器ID和序列号,以确保生成的ID既唯一又有序。

Snowflake ID结构

Snowflake生成的64位ID可以分为以下几个部分:

以下是一个简化的Snowflake算法实现示例:

public class SnowflakeIdGenerator {

    private long datacenterId; // 数据中心ID
    private long machineId;    // 机器ID
    private long sequence = 0L; // 序列号
    private long lastTimestamp = -1L; // 上一次时间戳

    private final long twepoch = 1288834974657L;
    private final long datacenterIdBits = 5L;
    private final long machineIdBits = 5L;
    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
    private final long maxMachineId = -1L ^ (-1L << machineIdBits);
    private final long sequenceBits = 12L;

    private final long machineIdShift = sequenceBits;
    private final long datacenterIdShift = sequenceBits + machineIdBits;
    private final long timestampLeftShift = sequenceBits + machineIdBits + datacenterIdBits;
    private final long sequenceMask = -1L ^ (-1L << sequenceBits);

    public SnowflakeIdGenerator(long datacenterId, long machineId) {
        if (datacenterId > maxDatacenterId || datacenterId < 0) {
            throw new IllegalArgumentException("datacenterId can't be greater than %d or less than 0");
        }
        if (machineId > maxMachineId || machineId < 0) {
            throw new IllegalArgumentException("machineId can't be greater than %d or less than 0");
        }
        this.datacenterId = datacenterId;
        this.machineId = machineId;
    }

    public synchronized long nextId() {
        long timestamp = System.currentTimeMillis();

        if (timestamp < lastTimestamp) {
            throw new RuntimeException("Clock moved backwards. Refusing to generate id");
        }

        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) & sequenceMask;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }

        lastTimestamp = timestamp;

        return ((timestamp - twepoch) << timestampLeftShift) |
                (datacenterId << datacenterIdShift) |
                (machineId << machineIdShift) |
                sequence;
    }

    private long tilNextMillis(long lastTimestamp) {
        long timestamp = System.currentTimeMillis();
        while (timestamp <= lastTimestamp) {
            timestamp = System.currentTimeMillis();
        }
        return timestamp;
    }
}

下面是对这段代码的逐行解释:

类定义和变量初始化

以下是Snowflake算法的一些关键参数:

以下是一些用于位运算的参数,用于计算最终的ID:

构造函数

ID生成方法

辅助方法

以上就是在SpringBoot中设计一个订单号生成系统的示例代码的详细内容,更多关于SpringBoot订单号生成系统的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文