ibatis 搭配oracle做批量插入小結
阿新 • • 發佈:2019-02-07
比如,經常遇到的情況是,要把表A中的符合條件的資料全部取出來,形成一個結果集,
然後針對結果集中的每一條資料,迴圈插入到資料表B中去,除了傳統的在JAVA程式碼中
FOR迴圈來做外,在ibatis 2中,還增加了iterate標籤,可以用來生成迴圈要執行的語句,介紹如下:
<iterate
property="" /*可選,
從傳入的引數集合中使用屬性名去獲取值,
這個必須是一個List型別,
否則會出現OutofRangeException,
通常是引數使用java.util.Map時才使用,
如果傳入的引數本身是一個java.util.List, 不能只用這個屬性.
conjunction="" /*可選,
iterate可以看作是一個迴圈,
這個屬性指定每一次迴圈結束後新增的符號,
比如使每次迴圈是OR的, 則設定這個屬性為OR*/
open="" /*可選, 迴圈的開始符號*/
close="" /*可選, 迴圈的結束符號*/
prepend="" /*可選, 加在open指定的符號之前的符號*/
>
</iterate>
例子:
<iterate prepend=”AND” property=”userNameList” open=”(”
close=”)” conjunction=”OR”>
username=#userNameList[]#
</iterate>
這個時候,會生成如下形式的語句:
(username=xxx1 or username=xxx2 or username=xxx3)
因為open,close中指定了括號,conjunction則指定了分割是用or,
又如:
id in
<iterate prepend="" property="ids" open="(" close=")" conjunction="," >
#ids[]#
</iterate>
生成為:
id in (xx1,xx2,xx3,.....),
注意:使用<iterate>時,在List元素名後面包括方括號[]非常重要,方括號[]將物件標記為List,
以防解析器簡單地將List輸出成String。
再來看幾個例子:
1) 刪除的:
<delete id="delete">
delete from t_table where key in
<iterate property="keys" conjunction="," open="(" close=")">
#keys[]#
</iterate>
</delete>
2 ) update:
如果傳用的引數是自己定義的類,如:
<update id="sqlMap" parameterClass="example.test">
UPDATE TBL_COMPANY
SET ADDRESS = #address#
WHERE COMPANY_ID IN
<iterate conjunction="," open="(" close=")" property="companyIds" >
#companyIds[]#
</iterate>
</update>
生成Sql語句: UPDATE TBL_COMPANY SET ADDRESS='address' WHERE COMPANY_ID IN ( 45, 50, 70)
其中:companyIds是example.test類中的list屬性。
3) 批量插入,oracle中可以用insert all into,比如:
<insert id="insertintoragroupra" parameterClass="map">
insert all
<iterate conjunction=" " property="ragrouppreinsert">
into GROUP_ASSETRA
(RISKID, GROUPID,GROUPNAME,AV,RALISTID)
values
(
F_GETSEQ(),#ragrouppreinsert[].groupId#,#ragrouppreinsert[].groupname#,#ragrouppreinsert[].av#,
#ralistId#
)
</iterate>
select * from dual
</insert>
注意:比如這裡parameterClass="map"中,表明傳入的是一個MAP,這個MAP中
可以包含內容很豐富的東西了,比如:
map.put("ragrouppreinsert",list) //這裡ragrouppreinsert"存放的是一個LIST結果集了
map.put("ralistId",ralistId) //這裡另外設定一個要批量增加到group_assetra表中的資料
注意在上面的語句中,因為要將結果集合list中的每一條記錄對應的欄位插入到
GROUP_ASSETRA中,所以要使用#ragrouppreinsert[].groupId#的寫法,
而把map中的ralistId插進去,則只需要#ralistId#就可以了,這樣其實就是
插入到group_assetra表中的每一個ralistid欄位都是相同的值了
F_GETSEQ()是一個函式,獲得GROUP_ASSETRA表中的每次的序列,
具體其中遇到的問題,參考不錯的一篇講oracle insert all into的文:
然後針對結果集中的每一條資料,迴圈插入到資料表B中去,除了傳統的在JAVA程式碼中
FOR迴圈來做外,在ibatis 2中,還增加了iterate標籤,可以用來生成迴圈要執行的語句,介紹如下:
<iterate
property="" /*可選,
從傳入的引數集合中使用屬性名去獲取值,
這個必須是一個List型別,
否則會出現OutofRangeException,
通常是引數使用java.util.Map時才使用,
如果傳入的引數本身是一個java.util.List, 不能只用這個屬性.
conjunction="" /*可選,
iterate可以看作是一個迴圈,
這個屬性指定每一次迴圈結束後新增的符號,
比如使每次迴圈是OR的, 則設定這個屬性為OR*/
open="" /*可選, 迴圈的開始符號*/
close="" /*可選, 迴圈的結束符號*/
prepend="" /*可選, 加在open指定的符號之前的符號*/
>
</iterate>
例子:
<iterate prepend=”AND” property=”userNameList”
username=#userNameList[]#
</iterate>
這個時候,會生成如下形式的語句:
(username=xxx1 or username=xxx2 or username=xxx3)
因為open,close中指定了括號,conjunction則指定了分割是用or,
又如:
id in
<iterate prepend="" property="ids" open="(" close=")" conjunction="," >
#ids[]#
</iterate>
生成為:
id in (xx1,xx2,xx3,.....),
注意:使用<iterate>時,在List元素名後面包括方括號[]非常重要,方括號[]將物件標記為List,
以防解析器簡單地將List輸出成String。
再來看幾個例子:
1) 刪除的:
<delete id="delete">
delete from t_table where key in
<iterate property="keys" conjunction="," open="(" close=")">
#keys[]#
</iterate>
</delete>
2 ) update:
如果傳用的引數是自己定義的類,如:
<update id="sqlMap" parameterClass="example.test">
UPDATE TBL_COMPANY
SET ADDRESS = #address#
WHERE COMPANY_ID IN
<iterate conjunction="," open="(" close=")" property="companyIds" >
#companyIds[]#
</iterate>
</update>
生成Sql語句: UPDATE TBL_COMPANY SET ADDRESS='address' WHERE COMPANY_ID IN ( 45, 50, 70)
其中:companyIds是example.test類中的list屬性。
3) 批量插入,oracle中可以用insert all into,比如:
<insert id="insertintoragroupra" parameterClass="map">
insert all
<iterate conjunction=" " property="ragrouppreinsert">
into GROUP_ASSETRA
(RISKID, GROUPID,GROUPNAME,AV,RALISTID)
values
(
F_GETSEQ(),#ragrouppreinsert[].groupId#,#ragrouppreinsert[].groupname#,#ragrouppreinsert[].av#,
#ralistId#
)
</iterate>
select * from dual
</insert>
注意:比如這裡parameterClass="map"中,表明傳入的是一個MAP,這個MAP中
可以包含內容很豐富的東西了,比如:
map.put("ragrouppreinsert",list) //這裡ragrouppreinsert"存放的是一個LIST結果集了
map.put("ralistId",ralistId) //這裡另外設定一個要批量增加到group_assetra表中的資料
注意在上面的語句中,因為要將結果集合list中的每一條記錄對應的欄位插入到
GROUP_ASSETRA中,所以要使用#ragrouppreinsert[].groupId#的寫法,
而把map中的ralistId插進去,則只需要#ralistId#就可以了,這樣其實就是
插入到group_assetra表中的每一個ralistid欄位都是相同的值了
F_GETSEQ()是一個函式,獲得GROUP_ASSETRA表中的每次的序列,
具體其中遇到的問題,參考不錯的一篇講oracle insert all into的文:
http://yangtingkun.itpub.net/post/468/188133
<!-- 批量新增訊息 -->
<insert id="addMessageBatch" parameterClass="java.util.Map">
Insert into messages
<iterate property="statusList" conjunction=" UNION ALL ">
SELECT (SELECT rawtohex(sys_guid()) AS messageId FROM DUAL),#statusList[]#,0,0,#link#,#title#,#content#,#createDate# from dual
</iterate>
</insert>