mybatis 批量操作数据

mybatis的批量操作有两种方式,一是使用foreach标签,二是使用mybatis的BATCH模型

foreach标签

在xml中通过foreach对表数据进行循环操作

<insert id="insertProduct">
insert into product(name, type, price)
values
<foreache collection="list" item="item" separator=",">
( #{item.name}, #{item.type}, #{item.price})
</foreach>
</insert>

在oracle中不支持insert into product(name, type, price) values ('a', 'tv', 1233), ('b', 'ac', 3455),....('','','')这种形式的sql,因此oracle批量插入使用 insert all into table(...) values(...) into table(...) values(...) select * from dual; 语句来解决以下方式,并且需要显示指定useGeneratedKeys=false

<insert id="insertProduct parameterType="java.util.List" useGeneratedKeys="false">
    insert  all 
  <foreach collection="list" item="item" index="index">
    into product(name, type, price) 
    values
    (#{item.name}, #{item.type}, #{item.price})
  </foreach>
  select 1 from dual
</insert>

另一种方法是使用另外一种方法是 insert into table(...) (select ... from dual) union all (select ... from dual)

<insert id="insertProduct parameterType="java.util.List" useGeneratedKeys="false">
  insert  into product(name, type, price) 
   <foreach collection="list" item="item" index="index" separator="union all">
       select 
      ( #{item.name}, #{item.type}, #{item.price})
      from dual
   </foreach>
  
</insert>

ExecutorType.BATCH

Mybatis内置的ExecutorType一共有三种,默认为SIMPLE,该模式下它为每个语句的执行创建一个新的预处理语句,并单条提交sql。

BATCH模式会重复使用已经预处理的语句,并且批量执行所有更新语句,显然batch性能将更优;
注意: batch模式也有自己的问题,比如在Insert操作时,在事务没有提交之前,是没有办法获取到自增的id,这在某型情形下是不符合业务要求的。
具体用法如下:

class Batch{
  @Autowired
  SqlSessionFactory sqlSessionFactory;
  public void testBatch() {
    //取得可以执行批量操作的SQLSession
    SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
    //取到对应的mapper对象
    ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);
    //添加批量数据到预处理语句中
    for (int i=0; i<10000; i++) {
      mapper.addProduct(new Product("aaa", "TV", 1234);
    }
    //提交session
    sqlSession.commit();
    //关闭session
    sqlSession.close();  //可以放在final中
  }
}
//批量 预编译sql一次==》设置参数==》10000次==》执行1次 
        //非批量  (预编译=设置参数=执行 )==》10000次 


ProductMapper.java如下:

class ProductMapper{
  public long addProduct(Product product);
}

mapper.xml如下:

<mapper>
<insert id="addProduct" parameterType="xxx.xxx.Product">
  insert into Product(name, type, price) 
  values
  (#{name, jdbcType=VARCHAR}, #{type, jdbcType=VARCHAR}, #{price, jdbcType=NUMBER})
</insert>
<mapper>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。