-
使用注解:
以此注解为例@UpdateProvider:
注解参数:@UpdateProvider(type = SqlProvider.class, method = “update”)
type: SqlProvider 对应的sql提供者java类;
method : 此方法对应 sql提供者类中的专门给此方法提供sql的方法;
做法:首先在你的dao层接口方法上添加这个注解,然后method中使用可以直接进行sql的拼接,拼成你要批量更新的sql语句即可。 -
使用xml配置文件形式完成(第一种)
同样已更新为例:
sql语句:update table_name set name='小强', sex = '男' where id in(1,2,3,4)
mybatis的xml配置形式完成:
<update id="batchUpdate" parameterType="java.util.List"> update table_name set name='小强', sex='男' where id in <foreach collection="list" item="item" separator="," open="(" close=")"> #{item.id} </foreach> </update>
参数解释: collection=“list” list 即为 传过来的参数集合;item=“item” 代表每次循环到的集合中的记录(或者说是参数/实体); separator=","每次循环拼接时的分割符号。
-
使用xml配置文件形式完成(第二种)
还是以更新为例:
sql语句:UPDATE table_name SET name = CASE WHEN id = 1 THEN '小强' WHEN id = 2 THEN '露露' END, sex = CASE WHEN id = 1 THEN '男' WHEN id = 2 THEN '女' END where id in (1,2,3,4)
mybatis的xml配置形式完成: 假设参数List集合中存放的是对象
<update id="batchUpdate" parameterType="java.util.List"> UPDATE table_name <trim prefix="set" suffixOverrides=","> <trim prefix="name =case" suffix="end,"> <foreach collection="list" item="xx"> WHEN id = #{xx.id} THEN #{xx.name} </foreach> </trim> <trim prefix="sex =case" suffix="end,"> <foreach collection="list" item="xx"> WHEN id = #{xx.id} THEN #{xx.sex} </foreach> </trim> </trim> WHERE id IN <foreach collection="list" item="xx" separator="," open="(" close=")"> #{xx.id} </foreach> </update>
参数解释:
trim标记是一个格式化的标记 ;
prefix=“set” 是前缀为set ;
suffix=“end,” 后缀为end, ;
suffixOverrides="," :
举例说明,例如 a,b,c, :
去除这个字符串最后面那个‘,‘, 使字符串变成 a,b,c;
如果是字符串是 a,b,c:
则不会有任何改变
open="(": 开始时添加 ( ;
close=")" 结束时添加 ) ;
注意⚠️:当数据量过多时,慎用foreach,当表的列数较多(20+),以及一次性插入的行数较多(5000+)时,整个插入的耗时十分漫长;
循环后生成的批量插入语句如下:
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2"),
("data1", "data2"),
("data1", "data2");
因为MyBatis对于含有的语句,无法采用缓存,那么在每次调用方法时,都会重新解析sql语句。所以当数据量特别大,且字段很多时,PreparedStatement会特别长,包含了很多占位符,对于占位符和参数的映射尤其耗时;单次最好在20-50左右。
mybatis推荐的批量插入方式:
可参考:http://www.mybatis.org/mybatis-dynamic-sql/docs/insert.html
SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {
SimpleTableMapper mapper = session.getMapper(SimpleTableMapper.class);
List<SimpleTableRecord> records = getRecordsToInsert(); // not shown
BatchInsert<SimpleTableRecord> batchInsert = insert(records)
.into(simpleTable)
.map(id).toProperty("id")
.map(firstName).toProperty("firstName")
.map(lastName).toProperty("lastName")
.map(birthDate).toProperty("birthDate")
.map(employed).toProperty("employed")
.map(occupation).toProperty("occupation")
.build()
.render(RenderingStrategy.MYBATIS3);
batchInsert.insertStatements().stream().forEach(mapper::insert);
session.commit();
} finally {
session.close();
}