MyBatisは大量のデータをバッチで挿入します。データの問題が多すぎます

MyBatisは大量のデータを
バッチで挿入しますシナリオ:Excelテーブルをインポートし、データを読み取り、データベース
サービスをバッチ挿入しますキーコードは次のとおりです。
リストコレクションを渡し、データを直接挿入します

bindCardInsertLogMapper.batchInsertHzjjBindCodeLog(list);

XML

    <insert id="batchInsertHzjjBindCodeLog">
        INSERT INTO hzjj_batch_bind_code_log  (id_card,yt_no,redeem_code,card_no,password,name,batch_id,ip,course_id) VALUES
        <foreach collection="list" item="log" separator=",">
            (#{log.idCard},#{log.ytNo},#{log.redeemCode},#{log.cardNo},#{log.password},#{log.name},#{log.batchId},#{log.ip},#{log.courseId})
        </foreach>
    </insert>

最初は、インターフェイスの呼び出しに問題はなく、すべてが正常でした。その後、一度に300個のデータをインポートすると、エラーが直接報告されました。
着信表形式データストリーム(TDS)リモートプロシージャコール(RPC)プロトコルフロー正しくありませんでした。このRPC要求で提供されたパラメーターが多すぎます。
MybatisがSQLSERVERを呼び出すと、挿入やクエリの変更やその他の操作に関係なく、パラメーターが制限されていること確認するためにデータチェックするのは2100までである必要があります**。パラメーターの長さが2100を超えると、このエラーが報告されます。**
解決策:
複数のスレッドがデータをバッチで挿入します。元々は1000データで、10スレッドを開始し、スレッドごとに100を挿入しても問題ありません。
次のようにコードを解いた後:

					//因为我这边数据不会很多,所以线程池就直接使用CachedThreadPool,没有自定义一个线程池。
					ExecutorService executorService = Executors.newCachedThreadPool();
					//num 数据被分为多少批可以发送完
                    //100 每个线程批量插入100个
                    int num=list.size()/100;
                    if(list.size()%100>=0){
    
    
                        num=num+1;
                    }
                    // lastIndex 截取结束坐标
                    int lastIndex=0;
                    for (int i=0;i<num;i++){
    
    
                        if(100*(i+1)>list.size()){
    
    
                            lastIndex=list.size();
                        }else{
    
    
                            lastIndex= 100*(i+1);
                        }
                        //多线程批量添加
                        executorService.submit(new BatchInsertHzjjCodeThread(list.subList(i*100,lastIndex),bindCardInsertLogMapper));
                    }
                    //关闭线程池,拒绝接收任务
                    executorService.shutdown();
                    while (true){
    
    
                        //任务是否结束 进行下一步操作
                        if(executorService.isTerminated()){
    
    
                            bindCardInsertLogMapper.batchBindHzjjCode(batchId);
                            break;
                        }
                    }

次に、テーブルを再度インポートすると、通常どおり追加できます

おすすめ

転載: blog.csdn.net/ChenLong_0317/article/details/109813322