大批量插入数据(sql insert)

1、批量录入(方法一:mybiats foreach标签

所述的MySQL和Oracle的批量插入区别可以看出可能有兼容性问题(使用Oracle 的同学重点参考下)

而且jdbc链接Url要加上 allowMultiQueries=true参数。

*参考*

https://www.cnblogs.com/yangy608/p/3912580.html

 <insert id="insertByExcel" parameterType="java.util.List">
    insert into t_zd_fertilizer (  FertilizerTypeName, 
      FertilizerTradeName, FertilizerVender, 
      FertilizerN, FertilizerP, FertilizerK, 
      FertilizerContent, FertilizerUnit, FertilizerCreateTime, 
      FertilizerRemark, FertilizerPrice, FertilizerCommend)
    values
    <foreach collection="list" item="item" index="index" separator=",">
      (#{item.fertilizerTypeName}, 
      #{item.fertilizerTradeName}, #{item.fertilizerVender}, 
      #{item.fertilizerN}, #{item.fertilizerP}, #{item.fertilizerK}, 
      #{item.fertilizerContent}, #{item.fertilizerUnit}, #{item.fertilizerCreateTime},
      #{item.fertilizerRemark}, #{item.fertilizerPrice}, #{item.fertilizerCommend})
    </foreach>
</insert>

2、批量录入(方法二:mybatis ExecutorType.BATCH

下边这个是Mybatis的官方示例:

https://github.com/mybatis/mybatis-3/blob/master/src/test/java/org/apache/ibatis/submitted/batch_keys/BatchKeysTest.java

// jdbc 方式
@Test
  void testInsert() {
    try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
      User user1 = new User(null, "Pocoyo");
      sqlSession.insert("insert", user1);
      User user2 = new User(null, "Valentina");
      sqlSession.insert("insert", user2);
      sqlSession.flushStatements();
      assertEquals(Integer.valueOf(50), user1.getId());
      assertEquals(Integer.valueOf(50), user2.getId());
      sqlSession.commit();
    }
      //另外openSession方法第二个参数是设置是否自动提交,可以设置为flase。
      //这里提到拿到批量更新结果的方式支持拿到批量结果。
    try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
      List<User> users = sqlSession.selectList("select");
      Assertions.assertEquals( 2, users.size());
    }
  }
// mapper 方式
@Test
  void testInsertWithMapper() {
    try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
      Mapper userMapper = sqlSession.getMapper(Mapper.class);
      User user1 = new User(null, "Pocoyo");
      userMapper.insert(user1);
      User user2 = new User(null, "Valentina");
      userMapper.insert(user2);
      sqlSession.flushStatements();
      assertEquals(Integer.valueOf(50), user1.getId());
      assertEquals(Integer.valueOf(50), user2.getId());
      sqlSession.commit();
    }

    try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
      List<User> users = sqlSession.selectList("select");
      Assertions.assertEquals(2, users.size());
    }
  }



手工改造一下:

public void insertBatch(Map<String,Object> paramMap, List<User> list) throws Exception {
    // 新获取一个模式为BATCH,自动提交为false的session
    // 如果自动提交设置为true,将无法控制提交的条数,改为最后统一提交,可能导致内存溢出
    SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
    try {
        if(null != list || list.size()>0){
            int lsize=list.size();
            for (int i = 0, n=list.size(); i < n; i++) {
                User user= list.get(i);
                user.setIndate((String)paramMap.get("indate"));
                user.setDatadate((String)paramMap.get("dataDate"));//数据归属时间
                //session.insert("com.xx.mapper.UserMapper.insert",user);
                //session.update("com.xx.mapper.UserMapper.updateByPrimaryKeySelective",_entity);
                session.insert(“包名+类名", user);
                if ((i>0 && i % 1000 == 0) || i == lsize - 1) {
                    // 手动每1000个一提交,提交后无法回滚
                    session.commit();
                    // 清理缓存,防止溢出
                    session.clearCache();
                }
            }
        }
    } catch (Exception e) {
        // 没有提交的数据可以回滚
        session.rollback();
        e.printStackTrace();
    } finally {
   		session.close();
    }
}


//另外这里提供批量执行的结果的打印函数  参考: https://blog.csdn.net/w605283073/article/83064000 
public void printBatchResults(List<BatchResult> results) {
 if (results.size() > 0) {
  StringBuilder sb = new StringBuilder();
  sb.append("Batch summary:\n");
  for (int i = 0; i < results.size(); i++) {
   BatchResult result = results.get(i);
   sb.append("Result ").append(i).append(":\t");
   sb.append(result.getSql().replaceAll("\n", "").replaceAll("\\s+", " ")).append("\t");
   sb.append("Update counts: ").append(Arrays.toString(result.getUpdateCounts())).append("\n");
  }
  logDebug("082", sb.toString());
 }
}

3、脚本录入测试(MYSQL)

这是今天做测试的时候需要批量insert到一张表中20万条数据时使用到的测试脚本,记录一下:

declare @i varchar(max) --声明一个变量作为循环条件--
    set @i=1
        while @i<1000001 --执行100000次 insert--
        begin
        insert INTO
        表名(id,name,time) values('12345678'+@i,'小明','13527748096')
    set @i=@i+1
end
posted @ 2019-07-18 15:29  不良徐某  阅读(4591)  评论(0编辑  收藏  举报