java基于数据库怎么实现全局唯一ID

发布时间:2023-04-18 16:57:54 作者:iii
来源:亿速云 阅读:96

Java基于数据库怎么实现全局唯一ID

在分布式系统中,生成全局唯一ID是一个常见的需求。全局唯一ID通常用于标识系统中的各种资源,如订单、用户、消息等。本文将介绍如何使用Java基于数据库实现全局唯一ID的几种常见方法。

1. 自增主键

最简单的方法是使用数据库的自增主键功能。大多数关系型数据库(如MySQL、PostgreSQL)都支持自增主键。每次插入一条新记录时,数据库会自动为该记录生成一个唯一的ID。

实现步骤

  1. 在数据库表中定义一个自增主键字段。
  2. 在Java代码中插入数据时,不需要显式指定该字段的值,数据库会自动生成。

示例代码

CREATE TABLE orders (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    order_data VARCHAR(255)
);
public class Order {
    private Long id;
    private String orderData;

    // Getters and setters
}

public class OrderDAO {
    public void saveOrder(Order order) {
        String sql = "INSERT INTO orders (order_data) VALUES (?)";
        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
            pstmt.setString(1, order.getOrderData());
            pstmt.executeUpdate();
            try (ResultSet rs = pstmt.getGeneratedKeys()) {
                if (rs.next()) {
                    order.setId(rs.getLong(1));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

优缺点

2. 数据库序列

某些数据库(如Oracle、PostgreSQL)支持序列(Sequence),可以生成唯一的数字序列。通过使用序列,可以在多个数据库实例之间生成唯一的ID。

实现步骤

  1. 在数据库中创建一个序列。
  2. 在Java代码中通过SQL查询获取下一个序列值。

示例代码

CREATE SEQUENCE order_id_seq START WITH 1 INCREMENT BY 1;
public class OrderDAO {
    public Long generateOrderId() {
        String sql = "SELECT nextval('order_id_seq')";
        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql);
             ResultSet rs = pstmt.executeQuery()) {
            if (rs.next()) {
                return rs.getLong(1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

优缺点

3. UUID

UUID(Universally Unique Identifier)是一种128位的全局唯一标识符。Java提供了java.util.UUID类来生成UUID。

实现步骤

  1. 在Java代码中使用UUID.randomUUID()生成UUID。
  2. 将生成的UUID存储到数据库中。

示例代码

public class Order {
    private String id;
    private String orderData;

    public Order() {
        this.id = UUID.randomUUID().toString();
    }

    // Getters and setters
}
CREATE TABLE orders (
    id VARCHAR(36) PRIMARY KEY,
    order_data VARCHAR(255)
);

优缺点

4. 分布式ID生成器

在分布式系统中,可以使用分布式ID生成器来生成全局唯一ID。常见的分布式ID生成算法有Snowflake算法、Twitter的Snowflake、百度的UidGenerator等。

实现步骤

  1. 选择一个分布式ID生成算法。
  2. 在Java代码中实现该算法或使用现有的库。

示例代码

public class SnowflakeIdGenerator {
    private final long twepoch = 1288834974657L;
    private final long workerIdBits = 5L;
    private final long datacenterIdBits = 5L;
    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
    private final long sequenceBits = 12L;
    private final long workerIdShift = sequenceBits;
    private final long datacenterIdShift = sequenceBits + workerIdBits;
    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
    private final long sequenceMask = -1L ^ (-1L << sequenceBits);

    private long workerId;
    private long datacenterId;
    private long sequence = 0L;
    private long lastTimestamp = -1L;

    public SnowflakeIdGenerator(long workerId, long datacenterId) {
        if (workerId > maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
        }
        if (datacenterId > maxDatacenterId || datacenterId < 0) {
            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
        }
        this.workerId = workerId;
        this.datacenterId = datacenterId;
    }

    public synchronized long nextId() {
        long timestamp = timeGen();
        if (timestamp < lastTimestamp) {
            throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
        }
        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) & sequenceMask;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }
        lastTimestamp = timestamp;
        return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence;
    }

    protected long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }

    protected long timeGen() {
        return System.currentTimeMillis();
    }
}

优缺点

总结

在Java中基于数据库实现全局唯一ID有多种方法,每种方法都有其优缺点。选择哪种方法取决于具体的应用场景和需求。对于简单的单机应用,自增主键或UUID可能是最简单的选择;而对于分布式系统,可能需要使用分布式ID生成器来确保全局唯一性。

推荐阅读:
  1. Python 爬取 11 万 Java 程序员信息竟有这些重大发现!
  2. 如何掌握所有的编程语言

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java id 数据库

上一篇:Remix后台桌面开发electron-remix-antd-admin的方法是什么

下一篇:CSS是怎么绘制颜色的

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》