宋子宪博客

Mybatis快速批量插入10万条数据实战

使用Mybatis大概有以下4种常见插入方法

1.使用for循环,每次执行一次insert插入(效率低不推荐)
2.使用MyBatis的标签遍历插入(效率低不推荐)
3.使用Mybatis,纯sql插入(推荐,效率最高)
4.使用 SqlSessionFactory,每一批数据执行一次提交(重点推荐)

下面直接推荐两种快速高效的方法,第一种需要手动拼写sql,比较麻烦,但是效率高一些,建议直接使用第二种方法比较方便,效率都差不多,下面两种方式都同时支持Oracle和Mysql

开启数据库批量插入

由于Oracle默认已经开启批量插入,Mysql需要手动开启,需要在连接url后面加上&rewriteBatchedStatements=true

jdbc:mysql://127.0.0.1:3306/szx_blog?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&&rewriteBatchedStatements=true

第一种:使用Mybatis,纯sql插入(推荐使用)

动态创建Sql拼接

public class UsersProvider {
 
    public String insertListSql(List<Users> list) {
        StringBuffer sqlList = new StringBuffer();
 
        sqlList.append(" INSERT INTO users(id,name,age,manager_id)  VALUES ");
        for (int i = 0; i < list.size() ; i++) {
            Users user = list.get(i);
            sqlList.append(" (").append(user.getId()).append(",").append("'").append(user.getName()).append("',").append(user.getAge())
                    .append(",").append(user.getManagerId()).append(")");
            if (i < list.size()-1) {
                sqlList.append(",");
            }
        }
        return sqlList.toString();
    }
}

在Mapper接口种指定该方法

//sql插入相关方法
@Repository
public interface UsersMapper extends BaseMapper<Users> {
    //调用Sql方法
    @InsertProvider(type = UsersProvider.class, method = "insertListSql")
    public void sqlInsert(List<Users> list);
}

批量插入测试方法

@Test
public void sqlInsert() {
    // 批量插入计时开始
    StopWatch sw = new StopWatch();
    sw.start();
    // sql插入数据
    usersMapper.sqlInsert(list);
    System.out.println("sql方法批量插入耗时:"+(sw.getTotalTimeMillis()));
}

经过博主测试10万条数据大概在5秒左右

第二种 SqlSessionFactory批量插入

    @Test
    public void batchInsert() {
        // 创建sqlSession 开启批量插入
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,false);
        // 获取要批量的Mapper
        UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
        System.out.println("batchInsert 插入开始");
        // 批量插入计时开始
        StopWatch sw = new StopWatch();
        sw.start();

        try {
            for (int i = 0; i < list.size(); i++) {
                // 调用insert方法
                usersMapper.insert();
                // 每3000条插入一次
                if (i % 3000 == 0 || i == list.size() - 1) {
                    sqlSession.flushStatements();
                    log.info("提交成功");
                }
            }
        } catch (Exception e) {
            sqlSession.rollback();
            log.info("批量插入失败,原因:{}",e.getMessage());
            e.printStackTrace();
        }finally {
            sqlSession.close();
            log.info("关流成功");
        }
//        sqlSession.commit();
//        sqlSession.clearCache();
        sqlSession.flushStatements();
        System.out.println("SqlSession 批量插入耗时:"+(sw.getTotalTimeMillis()));
    }

经过测试插入10万条数据大概在15秒左右

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »