MyBatis和Spring结合的批处理方案

 MyBatis和Spring结合的批处理方案

参考网址:

http://www.mybatis.org/mybatis-dynamic-sql/docs/insert.html

https://blog.csdn.net/zxy_9264_ang/article/details/93844849

https://blog.csdn.net/artaganan8/article/details/88624402

https://blog.csdn.net/huanghanqian/article/details/83177178

https://blog.csdn.net/qq_15003505/article/details/80428249

1、创建 SqlSession

SqlSessionFactory 是通过Spring管理的,除了设置 ExecutorType.BATCH,还要取消自动提交,通过 SqlSessionFactory的openSession 实现

2、设置rewriteBatchedStatements

拼接在jdbc地址上 jdbc:mysql://127.0.0.1:3306/project?rewriteBatchedStatements=true 

3、分批处理

如果不要一次循环直接跑完,多缓冲几次

4、获取处理结果

通过 sqlSession.flushStatements() 可以拿到返回的结果集

5、关闭sqlSession

package cn.xxx.partner.maintainsite.dao;

import cn.xxx.partner.maintainsite.entity.MaintainSiteBasicEntity;
import cn.xxx.partner.maintainsite.mapper.MaintainSiteUpdateMapper;
import org.apache.ibatis.executor.BatchResult;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author GaoMingBo
 * @since 2019-09-02 16:19
 */
@Repository
public class MaintainSiteBatchDao {

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    private SqlSession sqlSession;
    
    @PostConstruct
    public void init() {
        // 初始化批量处理的sql session,取消自动提交
        sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
    }
    
    public String batchUpdate(String statementMapper, List<Map<String, Object>> params, Integer group) {
        List<BatchResult> batchResults = new ArrayList<>();
        // 默认每组1000个,不能太大,防止内存溢出
        group = (group == null || group == 0) ? 1000 : group;
        int batchSize = 0;
        for (Map<String, Object> param : params) {
            sqlSession.update(statementMapper, param);
            batchSize++;
            if (batchSize == group) {
                batchResults.addAll(sqlSession.flushStatements());
                batchSize = 0;
            }
        }
        if (batchSize > 0) {
            batchResults.addAll(sqlSession.flushStatements());
        }
        return assembleBatchResults(batchResults);
    }

    /**
     * 批量更新网点
     *
     * @param entityList 更新参数
     * @param group      分组数量--批量操作时的分组
     * @return 批量操作结果
     */
    public String batchUpdate(List<MaintainSiteBasicEntity> entityList, Integer group) {
        // 初始化Mapper
        MaintainSiteUpdateMapper siteMapper =     sqlSession.getMapper(MaintainSiteUpdateMapper.class);
        List<BatchResult> results = new ArrayList<>();
        // 默认每组1000个,不能太大,防止内存溢出
        group = (group == null || group == 0) ? 1000 : group;
        int batchSize = 0;
        try {
            for (MaintainSiteBasicEntity entity : entityList) {
                siteMapper.updateByPrimaryKeySelective(entity);
                batchSize++;
                if (batchSize == group) {
                    // 缓冲SQL语句
                    results.addAll(sqlSession.flushStatements());
                    batchSize = 0;
                }
            }
            if (batchSize > 0) {
                // 缓冲SQL语句
                results.addAll(sqlSession.flushStatements());
            }
            // 提交事务
            sqlSession.commit();
        } catch (Exception e) {
            // 回滚事务
            sqlSession.rollback();
        } finally {
            // 关闭SqlSession
            sqlSession.close();
        }
        // 返回组装后的处理结果
        return assembleBatchResults(results);
    }

    /**
     * 组装批量操作结果
     *
     * @param results 批量结果集
     * @return 批量操作结果
     */
    private String assembleBatchResults(List<BatchResult> results) {
        if (results.size() > 0) {
            StringBuilder sb = new StringBuilder();
            sb.append("批量操作记录:\n");
            for (int i = 0; i < results.size(); i++) {
                BatchResult result = results.get(i);
                sb.append("第 ").append(i + 1).append(" 批:\t");
                sb.append(result.getSql().replaceAll("\n", "")
                        .replaceAll("\\s+", " ")).append("\t");
                sb.append("更新行数: ").append(findSumWithoutUsingStream(result.getUpdateCounts())).append("\n");
            }
            return sb.toString();
        } else {
            return null;
        }
    }

    /**
     * 计算数组之和
     *
     * @param array int数组
     * @return 数组之和
     */
    private static int findSumWithoutUsingStream(int[] array) {
        int sum = 0;
        for (int value : array) {
            sum += value;
        }
        return sum;
    }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值