天天看點

oracle+mybatis批量插入的兩種正常寫法需求實作說明

需求

示例:很普通的需求

表結構:

create table t_user(
  user_id varchar2(20),
  user_name varchar2(20)
);
           

java bean:

public class User {
    String userId;
    String userName;
    // ...
}
           

現在有一個List<User>對象插入到t_user表裡,oracle資料庫,mybatis架構,使用批量插入方式。

實作

寫法不固定,我這樣寫的,僅作參考

多表插入

<insert id="batchSave" parameterType="com.xuxd.bean.User">
        insert all
        <foreach collection="list" item="user" separator="  " open=" " close=" " index="index">
            into t_user(
            user_id,
            user_name
            ) VALUES (
            #{user.userId},
            #{user.userName}
            )
        </foreach>
        select 1 from dual
    </insert>
           

單表插入

<insert id="batchSave" parameterType="com.xuxd.bean.User">
        insert into t_user(user_id, user_name)
        select u.id, u.name from
        (
            <foreach collection="list" index="index" item="user" open=" " close=" " separator=" union all ">
                select #{user.userId} as id, #{user.userName} as name from dual
            </foreach>
        ) u
    </insert>
           

說明

這兩種寫法很常見(細節上可能不同),在網上一搜就出來了,大多類似,對于初學者可能好奇為何這樣寫,解釋下。

下面參考了官方文檔,SQL Language Reference11g Release 2 (11.2)

看下插入文法:

oracle+mybatis批量插入的兩種正常寫法需求實作說明

單表插入和多表插入,按前面的順序解釋

多表插入

oracle+mybatis批量插入的兩種正常寫法需求實作說明

根據目前場景主要是上面紅框内,無條件多表插入。

insert all into t1(...) values (...) into t2(...) values(...) ... select ... from t
           

意思是向t1、t2...等多個表中插入資料,後面注意跟了個子查詢select ... from t。這個子查詢的結果前面是可以用的。but,重點是這個子查詢的結果行數用來計算前面插入的每個表的行數。是以,如果子查詢傳回多行,前面每個表就會插入多行,對于傳回的每一行,每個表都要執行一次插入。如果是0行,前面每個表都不會插入。

是以,目前場景的mybatis寫法實作是,插入的多個表都是同一個表,然後select 1 from dual傳回的行數是1,每個表就隻插入1行。

順便提一下,如果需要每行id是一個序列生成的,這種情況,就不能這樣寫了,因為這條語句,會被看做一條sql,是以如果需要生成序列,那麼每列的序列值都是同一個值。

單表插入

oracle+mybatis批量插入的兩種正常寫法需求實作說明

單表插入,這裡實作其實就是一個子查詢,查詢是借用dual表傳回結果,可以看下子查詢文法:

oracle+mybatis批量插入的兩種正常寫法需求實作說明

每一個子查詢:select #{user.userId} as id #{user.userName} as name from dual使用union all,這樣就很清楚了。