mybatis批量插入數據


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;
---
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM