Java 批量插入批量更新數據到SQL Server


inert和update在數據量龐大的情況下,速度非常慢,那怎么解決呢?可以用批量插入和批量更新

批量插入11萬條數據,如下圖

 

第一個圖數據庫已經有11萬的情況下測試,第二個圖數據庫已經有22萬的情況下測試

 

 

 

 

 我的代碼是同時測試批量插入和批量更新,

 

Controller層
    @Test
    public String sayHello(){
        //獲取數據保存到List,紅色部分你們自己獲取數據
        HelloController helloController=new HelloController();
        long strMillis = System.currentTimeMillis();
        List<LogisticsReturn> fileList = helloController.getFileList();
        long endMillis = System.currentTimeMillis();
        long time = endMillis - strMillis;
        
        //批量更新
        strMillis = System.currentTimeMillis();
        logisticsReturnService.saveAll(fileList);
        endMillis = System.currentTimeMillis();
        long time2 = endMillis - strMillis;

        //批量修改
        strMillis = System.currentTimeMillis();
        logisticsReturnService.batchUpdate(fileList);
        endMillis = System.currentTimeMillis();
        long time3 = endMillis - strMillis;

        System.out.println("解析使用時間:"+time);
        System.out.println("插入使用時間:"+time2);
        System.out.println("更新使用時間:"+time3);
    }

 

ServiceImpl層
@Service
public class LogisticsReturnServiceImpl implements LogisticsReturnService {

    static Logger logger = LogManager.getLogger(LogisticsReturnServiceImpl .class);
    @Autowired
    SqlSessionTemplate sqlSessionTemplate;

    //將DAO注入Service層
    @Autowired
    private LogisticsReturnMapper logisticsReturnMapper;

    @Override
    public void saveAll(List<LogisticsReturn> logisticsReturns) {
        SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        LogisticsReturnMapper dao = session.getMapper(LogisticsReturnMapper.class);
        int size = logisticsReturns.size();
        try {
            for (int i = 0; i < size; i++) {
                dao.insert(logisticsReturns.get(i));
                if (i % 10000 == 0 || i == size - 1) {
                    //手動每10000個一提交,提交后無法回滾
                    session.commit();
                    //清理緩存,防止溢出
                    session.clearCache();
                }
            }
        } catch (Exception e) {
            logger.error("批量保存失敗:" ,e);
            session.rollback();
        } finally {
            session.close();
        }
    }

    @Override
    public void batchUpdate(List<LogisticsReturn> logisticsReturns) {
        SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        LogisticsReturnMapper dao = session.getMapper(LogisticsReturnMapper.class);
        int size = logisticsReturns.size();
        try {
            List<LogisticsReturn> temp=new ArrayList<>();
            for (int i = 0; i < size; i++) {
                temp.add(logisticsReturns.get(i));

                if (i % 500 == 0 || i == size - 1) {
                    //手動每500個一提交,提交后無法回滾
                    dao.updateBatch(temp);
                    temp=new ArrayList<>();
                    session.commit();
                    //清理緩存,防止溢出
                    session.clearCache();
                }
            }
        } catch (Exception e) {
            logger.error("批量更新失敗:" ,e);
            session.rollback();
        } finally {
            session.close();
        }
    }
}
 
         
         
        

 

mybatis的SQL語句
<insert id="insert" parameterType="LogisticsReturn">
        insert into [dbo].[LogisticsReturn]
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="guid != null and guid != ''">guid,</if>
            <if test="logisticsCode != null and logisticsCode != ''">logisticsCode,</if>
            <if test="logisticsNo != null and logisticsNo != ''">logisticsNo,</if>
            <if test="returnStatus != null and returnStatus != ''">returnStatus,</if>
            <if test="returnTime != null and returnTime != ''">returnTime,</if>
            <if test="returnInfo != null and returnInfo != ''">returnInfo,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="guid != null and guid != ''"> #{guid},</if>
            <if test="logisticsCode != null and logisticsCode != ''">#{logisticsCode},</if>
            <if test="logisticsNo != null and logisticsNo != ''"> #{logisticsNo},</if>
            <if test="returnStatus != null and returnStatus != ''">#{returnStatus},</if>
            <if test="returnTime != null and returnTime != ''"> #{returnTime},</if>
            <if test="returnInfo != null and returnInfo != ''">#{returnInfo},</if>
        </trim>
    </insert>

    <update id="updateBatch" parameterType="java.util.List">
        update [dbo].[LogisticsReturn]
        <trim prefix="set" suffixOverrides=",">

            <trim prefix="returnInfo =case" suffix="end," >
                <foreach collection="list" item="i" index="index">
                    <if test="i.returnInfo!=null">
                        when( logisticsNo=#{i.logisticsNo} ) then #{i.returnInfo}
                    </if>
                </foreach>
            </trim>
        </trim>
        where
        <foreach collection="logisticsReturns" separator="or" item="i" index="index" >
            logisticsNo=#{i.logisticsNo}
        </foreach>
    </update>
 
         
         
        

 

如果你不懂SQL的when then是什么,建議先看看這條語句
select      ID,Username,namer=(case when(score<='50')    then '實習'
 
                                    when(score>'50'  and  score<='500' )   then '赤腳醫生'    
 
                                    when(score>'500'  and score<='1000' )   then '村衛生員' 
 
                                    when(score>'1000'  and score<='1500' )   then '鄉衛生員' 
 
                                    when(score>'1500'  and score<='2000' )   then '鎮衛生員'
 
                                    when(score>'2000'  and score<='3000' )   then '醫師'
 
                                    when(score>'3000'  and score<='5000' )   then '主治醫師'
 
                                    when(score>'5000'  and score<='10000' )   then '副主任醫師'
 
                                    when(score>'10000'  and score<='20000' )   then '主任醫師'
 
                                    when(score>'20000'  and score<='50000' )   then '健康大使'
 
                                    else   '健康大使'  end ), (SELECT count(id)
 
         FROM  jk01_YiWen_Question  
 
         WHERE  UserID =  dbo.jk01_Member.ID)  as  questionnum  
 
   from  jk01_Member
 
        

 

 
        
Batch速度比insert和update提升好幾倍,看完點個推薦看吧。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM