1. 程式人生 > >ibatis批量插入 批量刪除 -iterate標籤應用

ibatis批量插入 批量刪除 -iterate標籤應用

專案開發中在很多地方可能會遇到同時插入多條記錄到資料庫的業務場景,如果業務級別迴圈單條插入資料會不斷建立連線且有多個事務,這個時候如果業務的事務執行頻率相當較高的話(高併發),對資料庫的效能影響是比較大的;為了提高效率,批量操作會是不錯的選擇,一次批量操作只需要建立一次連線且一個事務,能很大程度上提高資料庫的效率。

      批量插入操作的sql語句原型如下:

  1. insert  into    
  2.     wsjiang_test(col1, col2, col3)   
  3. values    
  4.     (col1_v, col2_v, col3_v),   
  5.     (col1_v, col2_v, col3_v),  
  6.      ... 

      這裡我們以ibatis為例,進行應用說明!

     一、 ibatis iterate標籤配置說明

  1. < iterate   
  2.     property =""  /*可選,   
  3.         從傳入的引數集合中使用屬性名去獲取值,   
  4.         這個必須是一個List型別,   
  5.         否則會出現OutofRangeException,   
  6.         通常是引數使用java.util.Map時才使用,   
  7.         如果傳入的引數本身是一個java.util.List, 不能只用這個屬性.  
  8.         不知道為啥官網: http://ibatis.apache.org/docs/dotnet/datamapper/ch03s09.html#id386679  
  9.         說這個屬性是必須的, 但是測試的時候是可以不設定這個屬性的, 還望那位大蝦知道, 講解一下.  
  10.         */  
  11.     conjunction =""  /*可選,   
  12.         iterate可以看作是一個迴圈,   
  13.         這個屬性指定每一次迴圈結束後新增的符號,   
  14.          比如使每次迴圈是OR的, 則設定這個屬性為OR*/  
  15.     open =""  /*可選, 迴圈的開始符號*/  
  16.     close =""  /*可選, 迴圈的結束符號*/  
  17.     prepend =""  /*可選, 加在open指定的符號之前的符號*/  
  18. >
     </ iterate >

       二、 ibatis iterate標籤使用示例

              1、批量查詢

  1. < select  id ="iterate_query"  parameterClass ="java.util.List" >   
  2.     <![CDATA[ 
  3.         selelct * from wsjiang_test where id=1 
  4.     ]]>   
  5.     < iterate  prepend ="prepend"  conjunction ="conn"  open ="open"  colse ="close" >   
  6.         /*使用java.util.List作為引數不能設定property屬性*/  
  7.         <![CDATA[ 
  8.             #v[]#  
  9.         ]]> /*這裡的"[]"是必須的, 要不然ibatis會把v直接解析為一個String*/  
  10.     </ iterate >   
  11. </ select >

             如果傳入一個List為[123,234,345], 上面的配置將得到一個sql語句:

                   select * from wsjiang_test where id=1 prepend open 123 conn 234 conn 345 close

            2、批量插入

               A、不使用open/close屬性

  1. < insert  id =" iterate_insert1 "  parameterClass ="java.util.List" >   
  2.     <![CDATA[ 
  3.         insert into wsjinag_test( col1 , col2 , col3 ) values  
  4.     ]]>   
  5.     < iterate  conjunction ="," >   
  6.         <![CDATA[  
  7.             (#test[]. col1 #, # test []. col2 #, # test []. col3 #)  
  8.         ]]>   
  9.     </ iterate >   
  10. </ insert > 

              上面的配置將得到一個sql語句:

                   insert  into wsjiang_test( col1, col2, col3 ) values  (?, ?, ?) , (?, ?, ?) , (?, ?, ?) 

              B、使用open/close屬性

  1. < insert  id ="betchAddNewActiveCode"  parameterClass ="java.util.List" >    
  2.    <![CDATA[ 
  3.         insert into wsjinag_test( col1 , col2 , col3 ) values  
  4.     ]]> 
  5.     < iterate  conjunction =","  open ="("  close =")" >   
  6.         <![CDATA[ 
  7.             /*這裡不加"("和")"*/  
  8. #test[]. col1 #, # test []. col2 #, # test []. col3 #
  9.         ]]>   
  10.     </ iterate >   
  11. </ insert > 

             上面的配置將得到一個sql語句:

                  insert  into wsjiang_test( col1, col2, col3 ) values  (?, ?, ?    ,     ?, ?, ?     ,     ?, ?, ?)

         這兩種使用方式區別是相當大的. conjunction, open 和close這幾個屬性需小心使用,將其區分開.

    三、單條插入返回新增記錄主鍵

          通常情況,ibatis的insert方法需要返回新增記錄的主鍵,但並非任何表的insert操作都會返回主鍵(這是一個陷阱);要返回這個新增記錄的主鍵,前提是表的主鍵是自增型的,或者是Sequence的;且必須啟用ibatis的selectKey 標籤; 否則獲取新增記錄主鍵的值為0或者null。

         ibatis的配置:

  1. < insert  id =" iterate_insert1 "  parameterClass ="Object" >   
  2.     <![CDATA[ 
  3.         insert into wsjinag_test( col1 , col2 , col3 ) 
  4.         values   (# col1 #, # col2 #, # col3 #)  
  5.     ]]>   
  6.     < selectKey   keyProperty ="id" resultClass= "Long" >   
  7.         <![CDATA[  
  8.             SELECT LAST_INSERT_ID() AS value 
  9.         ]]>   
  10.     </ selectKey >   
  11. </ insert >

四、 插入返回 新增記錄數

      在第三節中已經講清楚通過ibatis的insert方法只能得到新增記錄的ID; 如果對於無需知道新增記錄ID,只需要知道有沒有插入成功的業務場景時,特別是對於批量插入,配置的selectKey 可能會有問題時,一次插入多條,拿不到新增的ID,這時我們就只能返回插入成功的記錄數來區分是否新增成功!但是insert方法是不會返回記錄數;於是我們可以使用ibatis的update方法來呼叫沒有配置 selectKey 標籤的insert語句,這樣就能返回影響(插入)的記錄數了!

     某些地方理解不是很深刻,還請不吝賜教!