1. 程式人生 > >MyBatis+Oracle用foreach標籤實現批量插入資料以及主鍵自增

MyBatis+Oracle用foreach標籤實現批量插入資料以及主鍵自增

1.前言    

     最近做一個批量匯入影像的需求,將多條記錄批量插入資料庫中。解決思路:在程式中封裝一個List集合物件,然後把該集合中的實體插入到資料庫中,因為專案使用了MyBatis,所以打算使用MyBatis的foreach功能進行批量插入。資料庫用的是Oracle,於是帶著需求開始碼程式碼。

2.MyBatis+MySQL實現批量插入資料的做法

<insert id="batchInsert" parameterType="list">
    insert into S_DATUM_PAGE(PAGE_ID,ENTRY_ID,DATUM_ID,CONTENT_LENGTH,
    CREATED_TIME,NAME_TIME,IMAGE_FORMAT,PAGE_ORDER,PATH)
    VALUES
    <foreach collection="list" item="item" separator=";">
      (#{item.pageId},#{item.entryId},#{item.datumId},#{item.contentLength},
       #{item.createdTime},
      #{item.nameTime},#{item.imageFormat},#{item.pageOrder},#{item.path})
    </foreach>
</insert>

3.回顧一下MyBatis的foreach標籤的語法知識

    foreach的主要用在構建in條件中,它可以在SQL語句中進行迭代一個集合。

    foreach元素的屬性主要有 item,index,collection,open,separator,close。

    item表示集合中每一個元素進行迭代時的別名,index指定一個名字,用於表示在迭代過程中,每次迭代到的位置,open表示該語句以什麼開始,separator表示在每次進行迭代之間以什麼符號作為分隔符,close表示以什麼結束,在使用foreach的時候最關鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的,但是在不同情況 下,該屬性的值是不一樣的,主要有一下3種情況:

        1.如果傳入的是單引數且引數型別是一個List的時候,collection屬性值為list

        2.如果傳入的是單引數且引數型別是一個array陣列的時候,collection的屬性值為array

        3.如果傳入的引數是多個的時候,我們就需要把它們封裝成一個Map了,當然單引數也可以封裝成map

 但是如果Oracle按照這種寫法來寫是會報錯的,報錯內容如下:

### Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正確結束

4.MyBatis+Oracle批量插入資料的正確做法

<insert id="batchInsert" parameterType="list" useGeneratedKeys="false" >
    insert into S_DATUM_PAGE
    (PAGE_ID,ENTRY_ID,DATUM_ID,CONTENT_LENGTH,CREATED_TIME,NAME_TIME,
    IMAGE_FORMAT,PAGE_ORDER,PATH)
    SELECT PAGE_ID_SEQ.NEXTVAL,a.* FROM (
      <foreach collection="list" item="item" separator="union all">
        SELECT
        #{item.entryId},#{item.datumId},#{item.contentLength},#{item.createdTime},
        #{item.nameTime},#{item.imageFormat},#{item.pageOrder},#{item.path}
        FROM dual
      </foreach>
    ) a
 </insert>

關於主鍵自增:因為Oracle不像MySQL有主鍵自動增長的功能,Oracle要實現主鍵自增有其中一種做法是採用序列(Sequence)

來實現的,自己建立一個序列,然後在xml檔案中呼叫它。

執行通過。在Oracle的版本中,有幾點需要注意的:

        1.SQL中沒有VALUES;

        2.<foreach>標籤中的(select ..... from dual);

        3.<foreach>標籤中的separator的屬性為"UNION ALL",將查詢合併結果集。

        4.最重要的一點就是一定要在insert標籤中加入useGeneratedKeys="false",如果不加則會報如下錯誤:

        ### Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正確結束