重写mybatisPlus自定义ID生成策略

1.项目中需要引入mybatisplus核心组件

            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mp.version}</version>
            </dependency>

2.新建一个类实现IdentifierGenerator,重写id生成策略

import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;

import java.util.UUID;


public class CustomUUIDGenerator implements IdentifierGenerator {

    
    @Override
    public boolean assignId(Object idValue) {
        return IdentifierGenerator.super.assignId(idValue);
    }

    //重写雪花id算法
    @Override
    public Number nextId(Object entity) {
        return SequenceUtil.makeId();
    }

    //重写uuid算法,不过滤-
    @Override
    public String nextUUID(Object entity) {
        return UUID.randomUUID().toString();
    }
}

3.在mybatisplus配置文件中注入bean


@Configuration
public class MybatisPlusConfig {

    @Bean
    public IdentifierGenerator identifierGenerator() {
        return new CustomUUIDGenerator();
    }


}

4.在实体bean映射类中使用需要在ID字段上加入注解

ASSIGN_UUID即为重写后生成的UUID,原生成的uuid为32位,没有-连接符,id需要使用String类型

@TableId(value = "id", type = IdType.ASSIGN_UUID)
ASSIGN_ID即为重写后生成的雪花id,值为Long类型
@TableId(value = "workspaceid", type = IdType.ASSIGN_ID)

此方法为重写覆盖原生mybatisplus,所以不影响其他地方,id依然会在insert时自动生成.

附:雪花id覆盖Util


import java.util.HashSet;
import java.util.Set;

public class SequenceUtil {


    /*** 机 器 Id */
    private static long workerId = 0;
    /*** 数 据 中 心 */
    private static long centerId = 0;
    /*** 毫 秒 内 序 列 */
    private static long sequence = 0L;
    /*** 上 次 Id 生 成 的 时 间 戳 */
    private static long lastTimestamp = -1L;
    /** 机 器 编 号 所 占 位 数 */
    private static final long workerIdBits = 5L;
    /** 数 据 标 识 所 占 位 数 */
    private static final long centerIdBits = 5L;
    /** 开 始 时 间 戳 */
    private static final long poc = 1288834974657L;
    /** 序 列 在 Id 中 所 占 的 位 数 */
    private static final long sequenceBits = 12L;

    /** 为 算 法 提 供 可 用 配 置 */
    private static final long workerIdShift = sequenceBits;
    private static final long maxWorkerId = -1L ^ (-1L << workerIdBits);
    private static final long maxCenterId = -1L ^ (-1L << centerIdBits);
    private static final long centerIdShift = sequenceBits + workerIdBits;
    private static final long timestampLeftShift = sequenceBits + workerIdBits + centerIdBits;
    private static final long sequenceMask = -1L ^ (-1L << sequenceBits);


    /**
     * 获 取 下 一 个 ID ( 该方法都是线程安全的 )
     * */
    public static synchronized long makeSequence() throws Exception{

        long timestamp = timeGen();
        // 当 前 时 间 小 于 上 次 Id 生 成 时 间 ,说 明 系 统 时 钟 回 退, 应 会 抛 出 异 常
        if (timestamp < lastTimestamp) {
            // 服 务 器 时 钟 被 调 整 了, Sequence 生 成 器 停 止 服 务
            throw new Exception(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;

        // 雪 花  算 法 核 心
        long currentId = ((timestamp - poc) << timestampLeftShift) | (centerId << centerIdShift) | (workerId << workerIdShift) | sequence;

        return currentId;
    }


    /**
     * 获 取 下 一 个 Id
     * */
    public static long makeId(){

        try {

            return makeSequence();

        }catch (Exception e){

            e.printStackTrace();
        }
        return -1;
    }


    public static String makeStringId(){

        return "" + makeId();
    }

    /**
     * 根 据 一 定 数 量 的 Id
     * */
    public Set<Long> makeId(int initSize) throws Exception{

        Set<Long> ids = new HashSet<>(initSize);

        for (long current = 0; current < initSize; current++){

            ids.add(makeId());
        }

        return ids;
    }

    /**
     * 时 间 戳 比 对
     * */
    protected static long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }

    /**
     * 当 前 系 统 时 间 毫 秒
     * */
    protected static long timeGen() {

        return System.currentTimeMillis();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值