首先批量操做的優勢是:大大的提升查詢的效率。java
舉個簡單的例子:若是在程序中遍從來執行sql的話,這種狀況就是有多少行數據就要執行多少條sql,這樣致使的效率將是很是低。sql
以下可能須要40sjson
insert into USER (name,age) values ('張三','33');
insert into USER (name,age) values ('張三','33');
insert into USER (name,age) values ('張三','33');
insert into USER (name,age) values ('張三','33');
。。。數組
若是改爲批量執行的話,以下可能只須要3s.:mybatis
insert into USER (name,age) values
('張三','33'),
('張三','33'),
('張三','33'),
...oracle
下面將進行詳細講解用法。app
==============================spa
批量操做包括批量插入和批量更新和批量刪除:3d
主要是應用<foreach>來實現。regexp
格式如:
<foreach collection="list" item="item" open="(" close=")" separator="," index="index"> #{item.xx}, #{item.xx} </foreach>
其中foreach中的包含的屬性值有:
collection="list" 其中list是固定的,若是是數組就是array
item="item" 循環中每一項的別名
open="" 開始標識,好比刪除in (id1,id2),open="(" close=")"
close="" 結束標識
separator="," 分隔符號
index="index" 下標值
========================================================================
批量新增:
<!-- 批量保存用戶,並返回每一個用戶插入的ID -->
<insert id="batchSave" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">
INSERT INTO `test`.`tb_user`(`username`, age)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.username}, #{item.age})
</foreach>
</insert>
擴展:useGeneratedKeys="true" keyProperty="id" 這兩個屬性的設置表示按主鍵自增的方式自動生成主鍵。
若是這種寫法在Oracle不兼容的話,可使用:
INSERT ALL
INTO A(field_1,field_2) VALUES (value_1,value_2)
INTO A(field_1,field_2) VALUES (value_3,value_4)
INTO A(field_1,field_2) VALUES (value_5,value_6)
SELECT 1 FROM DUAL;
詳解:
"INSERT ALL INTO a表
VALUES(各個值)
INTO a表 VALUES (其它值)
INTO a表 VALUES(其它值) .... 再跟一個SELECT 語句"。
後邊跟的SELECT 語句咱們能夠從虛擬表裏查如 SELECT 1 FROM DUAL。注意後邊跟的SELECT語句能夠隨意,不過不是把它SELECT出來的內容插入前邊的表裏,而是起到前邊的多個數據每次插入多少行的做用,這個多少行是和後邊跟的SELECT語句查出來幾條而定的,如後邊的跟的SELECT 語句查出了15條記錄,那麼前邊的"INSERT ALL INTO a表 VALUES(各個值1) INTO a表 VALUES (其它值2) INTO a表 VALUES(其它值3)"就會先插入值1對應的各個字段插入15條記錄,而後插入值2各個對應的字段15條記錄,而後插入值3對應的各個字段15條記錄,也就是說有點按列插入的意思。
咱們要的是批量插入多個VALUES這樣的一條記錄,因此後邊的SELECT 語句只要能查出一條記錄就行,建議你們後邊用SELECT 1 FROM DUAL。
實際項目中的例子有:
<!-- 批量添加添加 -->
<insert id="batchInsert">
INSERT ALL
<foreach collection="list" item="entity" separator="">
into T_JW_XKGL_XKGZXSFW
(
XKGZXSFW_ID,
XKGZ_ID,
XQ_ID,
XYH,
NJ,
ZYDL_ID,
ZY_ID,
ZYFX_ID,
SFXFZ,
SFGAT,
SFLXS,
SFYXS,
SFJHS,
XSQT,
CXB,
CJR,
CJRXM,
CJSJ
)
values (
#{entity.electiveCourseRuleStuScopeID,jdbcType=VARCHAR},
#{entity.electiveCourseRuleID,jdbcType=VARCHAR},
#{entity.campusID,jdbcType=VARCHAR},
#{entity.collegeNum,jdbcType=VARCHAR},
#{entity.grade,jdbcType=VARCHAR},
#{entity.professionBroadID,jdbcType=VARCHAR},
#{entity.professionID,jdbcType=VARCHAR},
#{entity.professionDirID,jdbcType=VARCHAR},
#{entity.creditSystem,jdbcType=VARCHAR},
#{entity.hongKongMacaoTaiwan,jdbcType=VARCHAR},
#{entity.overseasStu,jdbcType=VARCHAR},
#{entity.medicalInsuranceStu,jdbcType=VARCHAR},
#{entity.exchangeStu,jdbcType=VARCHAR},
#{entity.stuGroup,jdbcType=VARCHAR},
#{entity.innovationClazz,jdbcType=VARCHAR},
#{entity.creator,jdbcType=VARCHAR},
#{entity.creatorName,jdbcType=VARCHAR},
#{entity.createTime,jdbcType=TIMESTAMP}
)
</foreach>
SELECT 1 FROM DUAL
</insert>
======================================================
批量刪除
<!-- 批量刪除用戶 -->
<delete id="batchDelete" parameterType="java.util.List">
DELETE FROM USER
WHERE id IN
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</delete>
================================
第二種批量新增數據的方式:
oracle語法:
insert into tableX (a,b,c) select * from ( select 1,2,3 from dual union select 4,5,6 from dual ) t
在使用mybatis時,oracle須要寫成下面格式
<foreach collection="list" item="file" index="index" separator="UNION">
實操例子有:
<insert id="batchInsertInfo" parameterType="java.util.List"> insert into XTGL_GGGL_JSFW (GGJSFW_ID, JS_ID, TZGG_ID, CJR, CJSJ, ZHXGR, ZHXGSJ) <foreach close=")" collection="list" item="item" index="index" open="(" separator="union"> select #{item.noticeRoseScopeId,jdbcType=VARCHAR}, #{item.roseId,jdbcType=VARCHAR}, #{item.noticeId,jdbcType=VARCHAR}, #{item.creator,jdbcType=VARCHAR}, #{item.createTime,jdbcType=VARCHAR}, #{item.editor,jdbcType=VARCHAR}, #{item.editeTime,jdbcType=VARCHAR} from dual </foreach> </insert>
運行經過。在Oracle的版本中,有幾點須要注意的:
1.SQL中沒有VALUES;
2.<foreach>標籤中的(selece ..... from dual);
3.<foreach>標籤中的separator的屬性爲"UNION ALL",將查詢合併結果集。
==============================
批量更新
<update id="updateByElectiveCourseResultIds">
update T_JW_XKGL_XKJG
set xkcgbz=#{dto.successFlag,jdbcType=VARCHAR},
ZHXGR =#{dto.editor,jdbcType=VARCHAR},
ZHXGRXM =#{dto.editorName,jdbcType=VARCHAR},
ZHXGSJ =#{dto.editeTime,jdbcType=DATE}
where xkjg_id in
<foreach collection="dto.electiveCourseResultIds" index="index" item="item"
open="(" separator="," close=")">
#{item}
</foreach>
</update>
=======================
實現代碼:從網上摘得一個例子(服務層得實現類下)
public void batchAddDevice(int sceneId, String list) { List<SceneDevice> sceneDevicesList = new ArrayList<>(); Map deviceMap = new HashMap<>(); Gson gson = new Gson(); JSONArray jsonArray = JSONArray.fromObject(list); for(int i = 0;i < jsonArray.size(); i++){ SceneDevice sceneDevice = new SceneDevice(); String jsonString = jsonArray.getString(i); deviceMap = gson.fromJson(jsonString, deviceMap.getClass()); sceneDevice.setId(Integer.parseInt(deviceMap.get("id").toString())); sceneDevice.setSceneId(sceneId); sceneDevice.setDeviceId(Integer.parseInt(deviceMap.get("deviceId").toString())); sceneDevice.setPattern(deviceMap.get("pattern").toString()); sceneDevicesList.add(sceneDevice); } curdRepo.batchAddDevice(sceneDevicesList); }
其中crudRepo接口聲明得方法是:
public void batchAddDevice(@Param("list") List<SceneDevice> list);
解釋:
@Param("list")表示傳到Mapper中得集合名字叫作list
=======================================================================
注意:批量新增不能經過dblinke進行DDL操做,否則會報錯