Mybatis批量插入註解方式示例(oracle + mysql)
阿新 • • 發佈:2018-11-07
場景:
匯入20萬條資料,for迴圈方式一條條插入巨慢(太low)。拼接長SQL的話,oracle根本無法支援(有SQL長度限制),經測試資料多於2000基本就不行了。故改用批量插入,在mapper中註解使用mybatis的foreach標籤寫。Mybatis框架會自動拼接生成批插的sql。
mysql版(這裡只寫2個欄位,大家自己照葫蘆畫瓢)
@Insert( { "<script>", "insert into users ", "(USERNAME,PASSWORD) ", "VALUES", "<foreach collection ='list' item='ulist' separator =','>", "(#{ulist.username},#{ulist.password})", "</foreach> ", "</script>" } ) public void batch_insert(List<UserEntity> userList);
要點解析:
1. 註解的{} 中,長的SQL要換行的話,注意逗號和引號,每行內容在" "中。({}中內容是陣列,這個好理解)
2. <foreach>標籤中是迴圈拼接的語句,注意前後有(),欄位務必在括號裡
3. collection ='list' 標明傳入的資料是list型別的(還有其他的,請參閱官方文件)
4. item值不必與形參名字相同,它的作用可以這麼理解:形參的替身/別名,如下圖:
5. separator =',' 說明要用什麼來分隔兩段語句(可以看oracle的例子,這裡有什麼不同)
最終拼接出來的語句如下(如果插入2行資料):
insert into users (username,password) values ('sam','123'),('tom','456');
oracle版:
@Insert( {"<script>", "insert into users ", "(ID,username,password) ", "SELECT SEQ_USERS.NEXTVAL, A.* FROM (", "<foreach collection ='list' item='ulist' separator ='union all'>", "(SELECT #{ulist.username},#{ulist.password} FROM DUAL)", "</foreach> ) A", "</script>" } ) public void batch_insert(List<UserEntity> userList);
比較複雜,使用了巢狀結構,多行語句之間使用union all連線。
特別注意,如果要插入序列,序列是要寫在foreach外的。
實際執行測試:
使用oracle,每批2000條commit一次為最佳。
換用mysql,可以20000條再commit一次,且速度比oracle快多了(同一臺機器測試)。