数据量大的时候如果在循环中执行单条新增操作,是非常慢的。那么如何在mybatis中实现批量新增数据呢?
方法
insert
标签的 foreach
属性可以用于批量插入数据。您可以使用 foreach
属性遍历一个集合,并为集合中的每个元素生成一条插入语句。
bash
<insert id="insertBatch" parameterType="list">
insert into table_name (column1, column2)
values
<foreach collection="list" item="item" separator=",">
(#{item.column1}, #{item.column2})
</foreach>
</insert>
实战
表结构
我有一张表结构如下,为了好理解我把结构做了适当的精简:
sql
create table exa_paper_question
(
paper_id bigint not null comment '试卷编号',
question_id bigint not null comment '试题编号'
)
comment '试卷和试题关联表';
实体
java
public class ExaPaperQuestion
{
private static final long serialVersionUID = 1L;
/** 试卷编号 */
private Long paperId;
/** 试题编号 */
private Long questionId;
// getter setter 略
}
maper.java
java
/**
* 批量新增试卷与试题的关系
*
* @param list 试卷和试题关联集合
*/
public int batchAddQuestionToPage(List<ExaPaperQuestion> list);
mapper.xml
xml
<!--批量新增试卷与试题的关系 -->
<insert id="batchAddQuestionToPage" parameterType="list">
insert into exa_paper_question (paper_id, question_id)
values
<foreach collection="list" item="item" separator=",">
(#{item.paperId}, #{item.questionId})
</foreach>
</insert>
业务调用处示例
java
List<ExaPaperQuestion> list = new ArrayList<>();
for(Long id:questionIds){
ExaPaperQuestion pq = new ExaPaperQuestion();
pq.setPaperId(request.getPaperId());
pq.setQuestionId(id);
list.add(pq);
}
exaPaperQuestionMapper.batchAddQuestionToPage(list);
批量删除
上面是演示的批量新增,那就也能用到批量删除。
如果是有主键的表,批量删除格式如下:
xml
<delete id="deleteExaQuestionByQuestionIds" parameterType="String">
delete from exa_question where question_id in
<foreach item="questionId" collection="array" open="(" separator="," close=")">
#{questionId}
</foreach>
</delete>
如果是我示例中的这张表,是需要两个条件确实一条记录的,那么就这样写:
xml
<!--批量删除试卷与试题的关系 -->
<insert id="batchDeleteExaPaperQuestionByPaperId" parameterType="list">
delete from exa_paper_question
where (paper_id, question_id) in (
<foreach collection="list" item="item" separator=",">
(#{item.paperId}, #{item.questionId})
</foreach>
)
</insert>
其他的代码参考批量新增,几乎一致不在占用版面。
总结
稍作修改性能提升几十倍,非常的爽