MyBatis는 대량의 데이터를 일괄 적으로 삽입하므로 데이터 문제가 너무 많습니다.

배치의에서 MyBatis로 삽입 많은 양의 데이터를
시나리오 : 가져 오기 엑셀 표는 데이터를 읽은 다음 일괄 데이터베이스에 삽입
등 다음 서비스의 키 코드입니다.
목록 컬렉션에서 직접 데이터를 삽입 패스

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 (Tabular Data Stream) 원격 프로 시저 호출 (RPC) 프로토콜 흐름 잘못되었습니다. 이 RPC 요청에 너무 많은 매개 변수가 제공되었습니다.
Mybatis가 SQL SERVER를 호출 할 때 삽입 또는 쿼리 수정 및 기타 작업에 관계없이 매개 변수가 제한 ** 되어 있는지 확인하기 위해 데이터 확인하려면 최대 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