Mybatis在执行批量插入时,如果使用的是for循环逐一插入,那么可以正确返回主键id。如果使用动态sql的foreach循环,那么返回的主键id列表,可能为null,这让很多人感到困惑;本文将分析问题产生的原因,并修复返回主键id为null的问题。该问题在开源中国社区,以及网络上,已经有很多人遇到并发帖咨询,似乎都没有得到期望的解决结果。今天,我将带领大家,分析并解决该问题,让foreach批量插入,返回正确的id列表。

	<insert id="insertStudents" useGeneratedKeys="true" keyProperty="studId" parameterType="java.util.ArrayList">
INSERT INTO
STUDENTS(STUD_ID, NAME, EMAIL, DOB, PHONE)
VALUES
<foreach collection="list" item="item" index="index" separator=",">
(#{item.studId},#{item.name},#{item.email},#{item.dob}, #{item.phone})
</foreach>
</insert>

以上便是Mybatis的foreach循环,其要生成的sql语句是:insert into students(stud_id, name) values(?, ?),(?, ?), (?, ?); 类似这样的批量插入。

Mybatis是对Jdbc的封装,我们来看看,Jdbc是否支持上述形式的批量插入,并返回主键id列表的。

PreparedStatement pstm = conn.prepareStatement("insert into students(name, email) values(?, ?), (?, ?), (?, ?)",
Statement.RETURN_GENERATED_KEYS); pstm.setString(1, "name1");
pstm.setString(2, "email1"); pstm.setString(3, "name2");
pstm.setString(4, "email2"); pstm.setString(5, "name2");
pstm.setString(6, "email2"); pstm.addBatch();
pstm.executeBatch(); ResultSet rs = pstm.getGeneratedKeys();
while (rs.next()) {
Object value = rs.getObject(1);
System.out.println(value);
}

Output:

248
249
250

好了,事实证明,Jdbc是支持上述批量插入,并能正确返回id列表的。Jdbc都支持,如果Mybatis却不支持,有点说不过去。

1. Mapper.xml中keyProperty和parameterType属性之间的关系(很重要)

useGeneratedKeys="true" keyProperty="studId" parameterType="Student"

上述xml配置,含义为,属性studId是参数类型Student对象的主键属性。毫无疑问,Student对象中有studId属性。

useGeneratedKeys="true" keyProperty="studId" parameterType="java.util.ArrayList"

那这个如何解释呢?ArrayList有studId属性吗?当然没有了。其正确含义为:ArrayList集合中的元素的studId属性。

所以,keyProperty和parameterType之间的关系,有时是直接关系,有时是间接关系。明白这个道理之后,我们就可以开始进一步阅读源码了。

详情:参考https://my.oschina.net/zudajun/blog/674946,http://www.cnblogs.com/admol/articles/4248159.html

<!-- 批量插入生成的兑换码 -->
2 <insert id ="insertCodeBatch" parameterType="java.util.List" >
3 <selectKey resultType ="java.lang.Integer" keyProperty= "id"
4 order= "AFTER">
5 SELECT LAST_INSERT_ID()
6 </selectKey >
7 insert into redeem_code
8 (bach_id, code, type, facevalue,create_user,create_time)
9 values
10 <foreach collection ="list" item="reddemCode" index= "index" separator =",">
11 (
12 #{reddemCode.batchId}, #{reddemCode.code},
13 #{reddemCode.type},
14 #{reddemCode.facevalue},
15 #{reddemCode.createUser}, #{reddemCode.createTime}
16 )
17 </foreach >
18 </insert >
向orderitem里面批量插入数据
<insert id="addOrderitem" useGeneratedKeys="true" keyProperty="oid"
        parameterType="java.util.ArrayList">
    
        insert into orderitem(iid,count,subtotal,oid,bid)
        values
        <foreach collection="list" item="item" index="index"
            separator=",">
            (#{item.iid},#{item.count},#{item.subtotal},#{item.orders.oid},
            #{item.bid})
        </foreach>
    </insert>
写成#{item.orders.oid}的原因如下
public class orderitem {
    private int iid;
    private int count;
    private double subtotal;
    private orders orders;
    private book book;
    /**}
public class orders {
    private int oid;
    private Date ordertime;
    private double total;
    private int state;
    private int uid;
    private user owner;
    private List<orderitem> orderitem;
---
    }

mybatis批量插入数据的更多相关文章

  1. mybatis批量插入数据到oracle

    mybatis 批量插入数据到oracle报 ”java.sql.SQLException: ORA-00933: SQL 命令未正确结束“  错误解决方法 oracle批量插入使用 insert a ...

  2. Mybatis 批量插入数据

    --mybatis 批量插入数据 --1.Oracle(需要测试下是否支持MySQL) < insert id ="insertBatch" parameterType=&q ...

  3. 【转载】MyBatis批量插入数据(insert)

    介绍:MyBatis批量插入数据,原理就是在xml文件中添加 foreach 语句,然后MyBatis自动在values后面添加多个括号: XML文件如下: <?xml version=&quo ...

  4. MyBatis批量插入数据(MySql)

    由于项目需要生成多条数据,并保存到数据库当中,在程序中封装了一个List集合对象,然后需要把该集合中的实体插入到数据库中,项目使用了Spring+MyBatis,所以打算使用MyBatis批量插入,应 ...

  5. MyBatis 批量插入数据的 3 种方法!

    批量插入功能是我们日常工作中比较常见的业务功能之一,之前我也写过一篇关于<MyBatis Plus 批量数据插入功能,yyds!>的文章,但评论区的反馈不是很好,主要有两个问题:第一,对 ...

  6. 160421、MyBatis批量插入数据

    在程序中封装了一个List集合对象,然后需要把该集合中的实体插入到数据库中,由于项目使用了Spring+MyBatis的配置,所以打算使用MyBatis批量插入,由于之前没用过批量插入,在网上找了一些 ...

  7. MyBatis 批量插入数据对插入记录数的限制

    <基于 MyBatis 框架的批量数据插入的性能问题的探讨>(作者:魏静敏 刘欢杰 来源:<计算机光盘软件与应用> 2013 年第 19 期)中提到批量插入的记录数不能超过10 ...

  8. oracle结合mybatis批量插入数据

    先上代码: controller: result = service.insertTRbXdhjLendYdData(params); service: List<TRbXdhjLendDTO& ...

  9. 难题解决:Mycat数据库中间件+Mybatis批量插入数据并返回行记录的所有主键ID

     一.mybatis的版本必须为3.3.1及其以上 项目所依赖的mybatis的版本必须为3.3.1及其以上,低版本的不行,保证hap项目的依赖的mybatis的jar的版本必需为需要的版本: 二.在 ...

随机推荐

  1. headers 替换脚本

    python代码 headers = """ Accept: */* Accept-Encoding: gzip, deflate, br Accept-Language ...

  2. oem 重建

    OracleDBControl启动失败to local from URL=http://your-url.co     方法: emca -deconfig dbcontrol db -repos d ...

  3. python 生成器与协程

    生成器在迭代中以某种方式生成下一个值并且返回和next()调用一样的东西. 挂起返回出中间值并多次继续的协同程序被称作生成器. 语法上讲,生成器是一个带yield语句的函数.一个函数或者子程序只返回一 ...

  4. Expm 7_2区间调度问题

    [问题描述] 给定n个活动,其中的每个活动ai包含一个起始时间si与结束时间fi.设计与实现算法从n个活动中找出一个最大的相互兼容的活动子集S. 要求:分别设计动态规划与贪心算法求解该问题.其中,对贪 ...

  5. Hive官方使用手册——新Hive CLI(Beeline CLI)

    Hive官方使用手册——新Hive CLI(Beeline CLI) https://blog.csdn.net/maizi1045/article/details/79481686

  6. 分布式调用技术 RPC VS REST

    一 分布式调用大体上就分为两类,RPC式的,REST式的,两者的区别主要是就是: 1. RPC是面向动作的(方法调用) 2. REST是面向资源的(URL表示资源,HTTP动词表示动作) 从变现形式来 ...

  7. 实现自己的Koa2

    这部分的代码在https://github.com/zhaobao1830/koa2中demo文件夹中 Koa就是基于node自带的http模块,经过封装,监听端口,实现ctx(上下文)管理,中间件管 ...

  8. LR提交JSON格式的请求

    https://www.cnblogs.com/yangxia-test/p/5584317.html

  9. Mac下brew安装与配置mysql

    一.打开mac控制台 $ brew install mysql 二.启动mysql服务 $ mysql.server start 三.初始化mysql配置 1 rainMacBook-Pro:~ co ...

  10. 从html页面中抽取table表格数据

    /** * [getDataFromTrElems 获取表格行元素数据] * @param {[Object]} trElems [trs dom] * @param {[String]} type ...