mybatis-plusのinsertBatchSomeColumnを一括追加

MyBatis-Plus は、MyBatis をベースにカプセル化された優れた永続化レイヤー フレームワークであり、豊富な便利な操作方法と強力なコード ジェネレーターを提供し、MyBatis の使用を大幅に簡素化します。MyBatis-Plus では、insertBatchSomeColumnこのメソッドを使用して、指定したフィールドを一括で追加する操作。

mybatis-plusこの IServiceインターフェースは デフォルトでバッチ挿入を提供しており saveBatch、これが唯一のデフォルトのバッチ挿入でもあります.データ量が多くない場合は直接使用できますが、これは1つずつ実行する効率のボトルネックです.ここで saveBatch を見てください。

 

 

 

sql文が1つずつ実行されていることがわかります.挿入されたデータの数は、sqlが実行された回数に相当します.メソッドをクリックすると、内部でどのように実装されているかを確認できますsaveBatch.

 

 このメソッドにはトランザクション アノテーションがあり、データのバッチ全体の挿入がトランザクションとして実行されることを示していることに注意してください。

デフォルトは 1000 回で、実行中に 1000 ごとに実行可能な状態になるのも不思議ではなく、数秒待ってから実行されます (ここでの待機時間は1000 個のステートメントinsertの実行時間です)。

次のポイントはインターフェイスですsaveBatch。パラメーターは、挿入されたオブジェクトのセットと挿入されたバッチの数です。これはデフォルトの 1000 です。

ここにも transaction アノテーションがあります. これはsaveBatchメソッドがオーバーロードされているためです. 挿入するとき, 呼び出す挿入バッチの数を指定することもできます.

降り続けるexecuteBatch

 

 

これが実際の実行方法です. idxLimit は DEFAULT_BATCH_SIZE とバッチサイズとして設定された長さの最小数を比較します. つまり, 設定された長さが 1000 未満の場合, バッチサイズは実行時に設定された長さになります.一度実行されます。

for ループの消費者: 対応する型は関数型インターフェイスであり、2 つの入力パラメーターを受け取り、何も返さない演算子を表します。これは、2 つのパラメーター sqlSession とループ内の現在の要素オブジェクトを指定すると、渡されたコンシューマー匿名関数を 1 回実行することを意味します。つまり、上記のソース コードに無名関数を挿入します。
 

i == indLimit の場合: pre-insert を実行し、idxLimit の値を再計算します。

if の idxLimit 計算ルール: 現在の idxLimit に batchSize (デフォルト 1000) を加えたものとコレクションの長さが最小値を取り、計算結果が確実にコレクションの長さを超えることはなく、最後のバッチの idxLimit がコレクションの長さに等しく、これがvalue will be used as the next time 事前挿入が実行される時点。

sqlSession.flushStatements(): When someone is in a transaction, it plays a pre-insert role. このコード行を実行した後、挿入されるデータはデータベース内のレコードの行をロックし、返されたデフォルトの主キーを割り当てますオブジェクトの主キーを他の必要なオブジェクトに割り当てることができるように、データベースによって挿入されたオブジェクトに送信されます。これはトランザクションの送信ではありません。

最後のメソッドが実行された後、@Transactional アノテーションはデフォルトでトランザクションを送信します. 呼び出されたメソッドに @Transactional アノテーションがある場合、デフォルトのトランザクション伝播タイプは Propagation.REQUIRED であり、新しいトランザクションは開かれません. @Transactional アノテーションが無い場合、新規開設となります。

以下では、実際のバッチ追加方法を使用しますinsertBatchSomeColumn,看看两者的区别

1.指定フィールド一括追加とは

指定フィールドのバッチ追加とは、1 つの SQL ステートメントで複数の INSERT ステートメントを実行することを指しますが、指定フィールドのみを挿入します。指定したフィールドをバッチで追加すると、データ操作の効率が向上し、データベースとアプリケーション間のネットワーク転送の回数が減り、データベース サーバーへの負荷が軽減され、システムの同時実行パフォーマンスが向上します。

2. MyBatis-Plusで指定フィールドを一括追加する方法の利用

mybatis-plus は InsertBatchSomeColumn バッチ挿入メソッドを提供します。SQL 自動インジェクター インターフェイス ISqlInjector を介して共通メソッド SQL ステートメントを注入し、BaseMapper を継承してカスタム メソッドを追加します. グローバル構成 sqlInjector 注入 MP は、クラスのすべてのメソッドを mybatis コンテナーに自動的に注入します. このように注入する必要があります。
 

/**
 * 自定义Sql注入
 *
 */

public class EasySqlInjector extends DefaultSqlInjector {
    
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
        // 注意:此SQL注入器继承了DefaultSqlInjector(默认注入器),调用了DefaultSqlInjector的getMethodList方法,保留了mybatis-plus的自带方法
        List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
        methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
        return methodList;
    }

}

 カスタム EasyBaseMapper

/**
 * @author 武天
 * @date 2023/3/22 18:19
 */
public interface EasyBaseMapper<T> extends BaseMapper<T> {
    /**
     * 批量插入 仅适用于mysql
     *
     * @param entityList 实体列表
     * @return 影响行数
     */
    Integer insertBatchSomeColumn(Collection<T> entityList);
}

 ここで継承したマッパーは、先ほど書いたカスタムマッパーを継承するように変更

/**
 * 
 * 
 * @author wutian
 * @email ${email}
 * @date 2022-10-03 22:12:06
 */
@Mapper
public interface BreakDownCluesDao extends EasyBaseMapper<ExcelBreakdownClues> {

}

通話テスト

 

明らかな違いを見ることができます. SQL は 1 つのエントリのみを実行し、その後にカンマ区切りの入力パラメータが続きます, 時間のかかるものも最適化されています. これは挿入数がそれほど多くない場合です. 数万の場合または数千万のデータ、この形式の優位性は、 

3. 指定フィールドを一括で追加する場合の注意事項

MyBatis-Plus を使用して指定フィールドを一括で追加する場合、以下の点に注意する必要があります。

  • 毎回追加される新しいデータの量は多すぎてはなりません. 各バッチで追加される新しいデータの量は 1000 以内に制御することをお勧めします.
  • 追加する指定フィールドを null にすることはできず、デフォルト値を手動で設定する必要があります。
  • 追加する指定されたフィールドに対応するフィールド値がエンティティ クラスにある場合、それは無視されます。

おすすめ

転載: blog.csdn.net/m0_51406695/article/details/129724446