Home > Mobile >  How to auto generate a ID of type string in SpringBoot?
How to auto generate a ID of type string in SpringBoot?

Time:11-22

The requirement is to autogenerate Id that should be alphanumeric and should start with alphabet only. Please suggest me some methods to implement this.

CodePudding user response:

Define a class implement IdentifierGenerator base on snowflake.

package com.commons.generator;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.BeanUtils;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;

public class SnowflakeId implements IdentifierGenerator {
    private static final long TWEPOCH = 1514764800000L;
    private static final long WORKER_ID_BITS = 5L;
    private static final long DATA_CENTER_ID_BITS = 5L;
    public static final long MAX_WORKER_ID = 31L;
    public static final long MAX_DATA_CENTER_ID = 31L;
    private static final long SEQUENCE_BITS = 12L;
    private static final long WORKER_ID_SHIFT = 12L;
    private static final long DATA_CENTER_ID_SHIFT = 17L;
    private static final long TIMESTAMP_LEFT_SHIFT = 22L;
    private static final long SEQUENCE_MASK = 4095L;
    private static long workerId;
    private static long datacenterId;
    private static long sequence = 0L;
    private static long lastTimestamp = -1L;

    public SnowflakeId() {
    }

    public static synchronized void initDataCenterAndWorker(int datacenterId, int workerId) {
        if ((long)workerId <= 31L && workerId >= 0) {
            if ((long)datacenterId <= 31L && datacenterId >= 0) {
                SnowflakeId.workerId = (long)workerId;
                SnowflakeId.datacenterId = (long)datacenterId;
            } else {
                throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", 31L));
            }
        } else {
            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", 31L));
        }
    }

    private SnowflakeId(long workerId, long datacenterId) {
        if (workerId <= 31L && workerId >= 0L) {
            if (datacenterId <= 31L && datacenterId >= 0L) {
                SnowflakeId.workerId = workerId;
                SnowflakeId.datacenterId = datacenterId;
            } else {
                throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", 31L));
            }
        } else {
            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", 31L));
        }
    }

    public static synchronized Long getId() {
        long timestamp = timeGen();
        if (timestamp < lastTimestamp) {
            throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
        } else {
            if (lastTimestamp == timestamp) {
                sequence = sequence   1L & 4095L;
                if (sequence == 0L) {
                    timestamp = tilNextMillis(lastTimestamp);
                }
            } else {
                sequence = 0L;
            }

            lastTimestamp = timestamp;
            return timestamp - 1514764800000L << 22 | datacenterId << 17 | workerId << 12 | sequence;
        }
    }

    protected static long tilNextMillis(long lastTimestamp) {
        long timestamp;
        for(timestamp = timeGen(); timestamp <= lastTimestamp; timestamp = timeGen()) {
        }

        return timestamp;
    }

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

    public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
        try {
            String id = BeanUtils.getProperty(object, "id");
            if (id != null) {
                return Long.valueOf(id);
            }
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException var4) {
            throw new HibernateException("only support id as the primary key by now");
        }

        return getId();
    }
}

And define the id field:

@Id
@GeneratedValue(generator = "snowFlakeId")
@GenericGenerator(name = "snowFlakeId", strategy = "com.commons.generator.SnowflakeId")
pirvate Long id;

You can change the return type if you need a string id.

  • Related