以下是一个基于 MyBatis-Plus 雪花算法的 ID 生成工具类实现。这个工具类封装了 MyBatis-Plus 内置的雪花算法生成器,提供了简洁的接口来获取分布式唯一 ID。

完全基于MyBatis-Plus 3.5.5版本实现

package com.zgb.common.core.utils.id;

import com.baomidou.mybatisplus.core.toolkit.Sequence;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;

/**
 * 雪花算法ID生成工具类
 * 完全基于MyBatis-Plus 3.5.5版本实现,解决无参构造方法问题
 */
public class SnowflakeIdGenerator {

    // 默认雪花算法序列生成器(使用自动生成的workerId)
    private static final Sequence DEFAULT_SEQUENCE;

    /** 雪花算法起始时间戳 (MyBatis-Plus 3.5.5默认值) */
    private static final long TWEPOCH = 1588261200000L; // 2020-04-30 00:00:00

    /** 时间戳占用位数 */
    private static final long TIMESTAMP_LEFT_SHIFT = 22;

    static {
        // 初始化默认序列生成器,手动计算workerId(模仿MyBatis-Plus内部实现)
        long workerId = getWorkerId(1L, 31L);
        DEFAULT_SEQUENCE = new Sequence(workerId, 1L);
    }

    /**
     * 私有化构造方法,防止实例化
     */
    private SnowflakeIdGenerator() {
        throw new AssertionError("不能实例化工具类SnowflakeIdGenerator");
    }

    /**
     * 生成雪花算法ID(Long类型)
     * @return 生成的ID
     */
    public static long nextId() {
        return DEFAULT_SEQUENCE.nextId();
    }

    /**
     * 生成雪花算法ID(字符串类型)
     * @return 生成的ID字符串
     */
    public static String nextIdStr() {
        return String.valueOf(DEFAULT_SEQUENCE.nextId());
    }

    /**
     * 根据指定的机器ID和数据中心ID生成雪花算法ID
     * @param workerId 机器ID (0-31)
     * @param dataCenterId 数据中心ID (0-31)
     * @return 生成的ID
     */
    public static long nextId(long workerId, long dataCenterId) {
        // 严格使用3.5.5版本支持的双参数构造方法
        Sequence sequence = new Sequence(workerId, dataCenterId);
        return sequence.nextId();
    }

    /**
     * 解析雪花ID,获取生成时间戳(毫秒)
     * @param id 雪花ID
     * @return 生成时间戳(毫秒)
     */
    public static long parseTimestamp(long id) {
        return (id >> TIMESTAMP_LEFT_SHIFT) + TWEPOCH;
    }

    /**
     * 解析雪花ID,获取机器ID
     * @param id 雪花ID
     * @return 机器ID
     */
    public static long parseWorkerId(long id) {
        long workerIdBits = 5L;
        long dataCenterIdBits = 5L;
        long sequenceBits = 12L;

        long mask = ~(-1L << workerIdBits);
        return (id >> (sequenceBits + dataCenterIdBits)) & mask;
    }

    /**
     * 解析雪花ID,获取数据中心ID
     * @param id 雪花ID
     * @return 数据中心ID
     */
    public static long parseDataCenterId(long id) {
        long dataCenterIdBits = 5L;
        long sequenceBits = 12L;
        long mask = ~(-1L << dataCenterIdBits);

        return (id >> sequenceBits) & mask;
    }

    /**
     * 解析雪花ID,获取序列号
     * @param id 雪花ID
     * @return 序列号
     */
    public static long parseSequence(long id) {
        long sequenceBits = 12L;
        long mask = ~(-1L << sequenceBits);
        return id & mask;
    }

    /**
     * 自动生成workerId(模仿MyBatis-Plus内部实现)
     */
    private static long getWorkerId(long datacenterId, long maxWorkerId) {
        StringBuilder sb = new StringBuilder();
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = networkInterfaces.nextElement();
                byte[] mac = networkInterface.getHardwareAddress();
                if (mac != null) {
                    for (byte b : mac) {
                        sb.append(String.format("%02X", b));
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        if (sb.length() > 0) {
            return (sb.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
        } else {
            try {
                String hostName = InetAddress.getLocalHost().getHostName();
                int hashCode = hostName.hashCode();
                return (hashCode & 0xffff) % (maxWorkerId + 1);
            } catch (UnknownHostException e) {
                return (int) (Math.random() * (maxWorkerId + 1));
            }
        }
    }

    public static void main(String[] args) {

        // 生成默认ID
        long id = SnowflakeIdGenerator.nextId();
        String idStr = SnowflakeIdGenerator.nextIdStr();

        // 指定机器ID和数据中心ID生成
        long customId = SnowflakeIdGenerator.nextId(1, 2);

        System.out.println("生成默认ID====" + id);
        System.out.println("idStr====" + idStr);
        System.out.println("customId====" + customId);
        //生成默认ID====1962325604158308353
        //idStr====1962325604158308354
        //customId====1962325604158410753
    }
}

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐