1. 程式人生 > >ibatis 搭配oracle做批量插入小結

ibatis 搭配oracle做批量插入小結

  比如,經常遇到的情況是,要把表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的文: 

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>