Mybatis-plusはスノーフレークアルゴリズムで生成されたIDを事前に取得し、生成したIDを返します


1. MybatisPlus の主キー戦略

  • 自動: データベース ID 自動インクリメント戦略を使用して ID 生成を制御します。
  • NONE: ID 生成戦略を設定しません。
  • 入力: ユーザーは手動で ID を入力します。
  • ASSIGN_ID: スノーフレーク アルゴリズムによって生成された ID (数値型および文字列型と互換性があります)。
  • ASSIGN_UUID: ID 生成戦略として UUID 生成アルゴリズムを使用します。

(1) Mybatis のデフォルトの主キー戦略は @TableId(type = IdType.ASSIGN_ID) です。これはデフォルトの戦略スノーフレーク アルゴリズムです。このとき、主キーの型は String またはデータ型 bigint にすることができます。その必要はありません。データテーブルの主キーをインクリメントする; (2)
@TableId (type = IdType.ASSIGN_AUTO) は主キーの自動インクリメント戦略です。この戦略はデータベーステーブルの主キーの増分戦略に従います。データベース テーブルのキーは自動インクリメントに設定する必要があるため、データ テーブルの主キー フィールドを自動インクリメントする必要がある場合は、一般的に int bigint を選択します (3) @TableId(
type = IdType.INPUT) この戦略は、次のことを意味します。 ID を手動で挿入する必要があり、そうでないとデータを追加できないため、データ テーブルの主キーを自動インクリメントして削除する必要があります; (4) @TableId(type = IdType.NONE )NONE 戦略は
、主キー生成戦略。主キー生成戦略を指定しない場合、または主キー戦略が NONE の場合、グローバル戦略に従います。したがって、@TableId で主キー戦略が指定されていない場合でも、スノーフレーク アルゴリズムが使用されます。

2. Mybatis-plusは、エンティティクラスのスノーフレークアルゴリズムによって生成されたIDを事前に取得します。

  場合によっては、計算を通じて他のフィールドの値を生成できるように、この ID を事前に取得したいことがあります。Mybatis-plus にはスノーフレーク アルゴリズム生成機能が組み込まれているため、それを見つけて呼び出すだけで、手動でアルゴリズムを実行する必要はまったくありません。
  このアルゴリズムは具体的には次のクラスに実装されているため、コードを広範囲に掲載することはしません。

import com.baomidou.mybatisplus.core.toolkit.IdWorker;

このように呼び出すことができます。ここで、エンティティは永続化したいオブジェクトです。

Long ID=IdWorker.getId(entity);

注意:拿到ID之后,需要手动将ID赋值到entity对象上;如果不手动赋值,执行完save()方法之后,又会重新生成一个ID,就跟上面方法取到的ID不一致了。

  さらに特別なニーズがある場合は、スノーフレーク アルゴリズムの他のパラメーターを設定することもできます。このクラスのソースコードは以下のとおりですが、その中のコメントがより詳しく書かれていますので、ご参考になれば幸いです。

package com.baomidou.mybatisplus.core.toolkit;
 
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
 
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
 
/**
 * id 获取器
 *
 */
public class IdWorker {
    
    
 
    /**
     * 主机和进程的机器码
     */
    private static IdentifierGenerator IDENTIFIER_GENERATOR = new DefaultIdentifierGenerator();
 
    /**
     * 毫秒格式化时间
     */
    public static final DateTimeFormatter MILLISECOND = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
 
    /**
     * 获取唯一ID
     *
     * @return id
     */
    public static long getId() {
    
    
        return getId(new Object());
    }
 
    /**
     * 获取唯一ID
     *
     * @return id
     */
    public static long getId(Object entity) {
    
    
        return IDENTIFIER_GENERATOR.nextId(entity).longValue();
    }
 
    /**
     * 获取唯一ID
     *
     * @return id
     */
    public static String getIdStr() {
    
    
        return getIdStr(new Object());
    }
 
    /**
     * 获取唯一ID
     *
     * @return id
     */
    public static String getIdStr(Object entity) {
    
    
        return IDENTIFIER_GENERATOR.nextId(entity).toString();
    }
 
    /**
     * 格式化的毫秒时间
     */
    public static String getMillisecond() {
    
    
        return LocalDateTime.now().format(MILLISECOND);
    }
 
    /**
     * 时间 ID = Time + ID
     * <p>例如:可用于商品订单 ID</p>
     */
    public static String getTimeId() {
    
    
        return getMillisecond() + getIdStr();
    }
 
    /**
     * 有参构造器
     *
     * @param workerId     工作机器 ID
     * @param dataCenterId 序列号
     * @see #setIdentifierGenerator(IdentifierGenerator)
     */
    public static void initSequence(long workerId, long dataCenterId) {
    
    
        IDENTIFIER_GENERATOR = new DefaultIdentifierGenerator(workerId, dataCenterId);
    }
 
    /**
     * 自定义id 生成方式
     *
     * @param identifierGenerator id 生成器
     * @see GlobalConfig#setIdentifierGenerator(IdentifierGenerator)
     */
    public static void setIdentifierGenerator(IdentifierGenerator identifierGenerator) {
    
    
        IDENTIFIER_GENERATOR = identifierGenerator;
    }
 
    /**
     * 使用ThreadLocalRandom获取UUID获取更优的效果 去掉"-"
     */
    public static String get32UUID() {
    
    
        ThreadLocalRandom random = ThreadLocalRandom.current();
        return new UUID(random.nextLong(), random.nextLong()).toString().replace(StringPool.DASH, StringPool.EMPTY);
    }
}

3. MybatisPlus は新しいオブジェクトを追加し、生成された ID を返します

  第 2 章の導入を通じて、save() メソッドの実行後、MybatisPlus フレームワークが実際に ID の作成、エンティティ オブジェクトへの割り当て、および ID を持つオブジェクトの永続化に役立つことに気づいたはずです。このとき生成されるID 参照コードは以下の通りです。

save() メソッドは MybatisPlus によって事前にカプセル化されており、直接呼び出すことができます。

save(entity);
System.out.println(entity.getId());    //保存完之后,直接可以获取到生成的ID

すごく簡単ですよね?私も最初はかなり落とし穴を踏みました。他の方の投稿を参考にMapperやサービスを修正しました。いくつかの操作機能は実装できましたが、コードはまったくエレガントではありませんでした。 MybatisPlus はとても素晴らしいのに、なぜこの機能が搭載されていないのか? そこで、MybatisPlus を注意深く調べた結果、見事に穴から抜け出すことができました。

(仕上げる)

おすすめ

転載: blog.csdn.net/bacawa/article/details/131686367