mybatis-plus 如何使用雪花算法ID生成策略

mybatis-plus 可以通過@TableId註解指定主鍵生成策略

@TableId(value="id",type=IdType.ASSIGN_ID)
描述
AUTO 數據庫ID自增
NONE 無狀態,該類型為未設置主鍵類型(註解裡等於跟隨全局,全局裡約等於 INPUT)
INPUT insert前自行set主鍵值
ASSIGN_ID 分配ID(主鍵類型為Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默認實現類為DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID 分配UUID,主鍵類型為String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默認default方法)
ID_WORKER 分佈式全局唯一ID 長整型類型(please use ASSIGN_ID)
UUID 32位UUID字符串(please use ASSIGN_UUID)
ID_WORKER_STR 分佈式全局唯一ID 字符串類型(please use ASSIGN_ID)

上面的註解設置瞭值,對應在MybatisDefaultParameterHandler中有判斷這個類型和設置ID的處理,判斷idType.getKey() == IdType.ASSIGN_ID.getKey()時,使用identifierGenerator.nextId(entity)創建瞭一個雪花算法ID。

    protected static void populateKeys(TableInfo tableInfo, MetaObject metaObject, Object entity) {
        IdType idType = tableInfo.getIdType();
        String keyProperty = tableInfo.getKeyProperty();
        if (StringUtils.isNotBlank(keyProperty) && null != idType && idType.getKey() >= 3) {
            IdentifierGenerator identifierGenerator = GlobalConfigUtils.getGlobalConfig(tableInfo.getConfiguration()).getIdentifierGenerator();
            Object idValue = metaObject.getValue(keyProperty);
            if (StringUtils.checkValNull(idValue)) {
                if (idType.getKey() == IdType.ASSIGN_ID.getKey()) {
                    if (Number.class.isAssignableFrom(tableInfo.getKeyType())) {
                        metaObject.setValue(keyProperty, identifierGenerator.nextId(entity));
                    } else {
                        metaObject.setValue(keyProperty, identifierGenerator.nextId(entity).toString());
                    }
                } else if (idType.getKey() == IdType.ASSIGN_UUID.getKey()) {
                    metaObject.setValue(keyProperty, identifierGenerator.nextUUID(entity));
                }
            }
        } 
    }

3.X版本後默認就是使用 IdType.ASSIGN_ID,即雪花算法,如果需要使用主鍵自增,則需要修改IdType.AUTO

看一下源碼大概找一下雪花算法的實現方式

首先來看主鍵生成策略的接口是IdentifierGenerator。mp中默認有一個實現類就是DefaultIdentifierGenerator,這個就是雪花算法的實現類。這個類中使用的Sequence就是雪花算法的實現類瞭。

如果想自己創建雪花算法手動創建ID怎麼辦

com.baomidou.mybatisplus.core.toolkit包下有一個IdWork的類,這個類就是使用上面的DefaultIdentifierGenerator來獲取雪花算法ID,我們可以直接使用IdWork同名方法getId或者getIdStr來手動獲取一個雪花算法ID。

Long id=IdWorker.getIdStr()

自定義ID生成器實現

第一種,使用spring掃描註解創建bean使用

@Component
public class CustomIdGenerator implements IdentifierGenerator {
    @Override
    public Long nextId(Object entity) {
       //可以將當前傳入的class全類名來作為bizKey,或者提取參數來生成bizKey進行分佈式Id調用生成.
       String bizKey = entity.getClass().getName();
        //根據bizKey調用分佈式ID生成
        long id = ....;
       //返回生成的id值即可.
        return id;
    }
}

第二種,直接把寫好的CustomIdGenerator實現類配置為一個bean

@Bean
public IdentifierGenerator idGenerator() {
    return new CustomIdGenerator();
}

Mybatis-plus 中生成雪花算法id的工具類

public static void main(String[] args) {
    // 返回值  1385106677482582018
    System.out.println(IdWorker.getId());
    // 返回值 "1385106677482582019"
    System.out.println(IdWorker.getIdStr());
}

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: