1. 程式人生 > >mybatis for each迴圈詳解

mybatis for each迴圈詳解

foreach一共有三種類型,分別為List,[](array),Map三種。

foreach的第一篇用來將List和陣列(array)。

下面表格是我總結的各個屬性的用途和注意點。

foreach屬性

屬性 描述
item 迴圈體中的具體物件。支援屬性的點路徑訪問,如item.age,item.info.details。
具體說明:在list和陣列中是其中的物件,在map中是value。
該引數為必選。
collection 要做foreach的物件,作為入參時,List<?>物件預設用list代替作為鍵,陣列物件有array代替作為鍵,Map物件沒有預設的鍵
當然在作為入參時可以使用@Param("keyName")來設定鍵,設定keyName後,list,array將會失效。 除了入參這種情況外,還有一種作為引數物件的某個欄位的時候。舉個例子:
如果User有屬性List ids。入參是User物件,那麼這個collection = "ids"
如果User有屬性Ids ids;其中Ids是個物件,Ids有個屬性List id;入參是User物件,那麼collection = "ids.id"
上面只是舉例,具體collection等於什麼,就看你想對那個元素做迴圈。
該引數為必選。
separator 元素之間的分隔符,例如在in()的時候,separator=","會自動在元素中間用“,“隔開,避免手動輸入逗號導致sql錯誤,如in(1,2,)這樣。該引數可選。
open foreach程式碼的開始符號,一般是(和close=")"合用。常用在in(),values()時。該引數可選。
close foreach程式碼的關閉符號,一般是)和open="("合用。常用在in(),values()時。該引數可選。
index 在list和陣列中,index是元素的序號,在map中,index是元素的key,該引數可選。

下面是測試。

SQL

  1. drop
    table users if exists;  
  2. createtable users (  
  3.   id int,  
  4.   namevarchar(20)  
  5. );  
  6. insertinto users (id, namevalues(1, 'User1');  
  7. insertinto users (id, namevalues(2, 'User2');  
  8. insertinto users (id, namevalues(3, 'User3');  
  9. insertinto users (id, namevalues(4, 'User4');  
  10. insertinto users (id, 
    namevalues(5, 'User5');  
  11. insertinto users (id, namevalues(6, 'User6');  
User類



Mapper.xml

  1. <selectid="countByUserList"resultType="_int"parameterType="list">
  2. select count(*) from users  
  3.   <where>
  4.     id in  
  5.     <foreachitem="item"collection="list"separator=","open="("close=")"index="">
  6.       #{item.id, jdbcType=NUMERIC}  
  7.     </foreach>
  8.   </where>
  9. </select>

測試程式碼:
  1. @Test
  2. publicvoid shouldHandleComplexNullItem() {  
  3. SqlSession sqlSession = sqlSessionFactory.openSession();  
  4. try {  
  5.   Mapper mapper = sqlSession.getMapper(Mapper.class);  
  6.   User user1 = new User();  
  7.   user1.setId(2);  
  8.   user1.setName("User2");  
  9.   List<User> users = new ArrayList<User>();  
  10.   users.add(user1);  
  11.   users.add(null);  
  12.   int count = mapper.countByUserList(users);  
  13.   Assert.assertEquals(1, count);  
  14. finally {  
  15.   sqlSession.close();  
  16. }  
  17. }  

測試日誌:

DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Setting autocommit to false on JDBC Connection [[email protected]]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [[email protected]]
DEBUG [main] - Closing JDBC Connection [[email protected]]
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Setting autocommit to false on JDBC Connection [[email protected]]
DEBUG [main] - ==>  Preparing: select count(*) from users WHERE id in ( ? , ? ) 
DEBUG [main] - ==> Parameters: 2(Integer), null
DEBUG [main] - <==      Total: 1
DEBUG [main] - Resetting autocommit to true on JDBC Connection [[email protected]]
DEBUG [main] - Closing JDBC Connection [[email protected]]

上面這個例子是List的,但是和陣列的情況基本一樣,所以不針對陣列進行測試了。可以看到這個例子的內容是很簡單的,實際上List,array,map也可以互相巢狀,可以用多個foreach去執行,如果想看這樣一個例子,可以移步這裡:

上面這個問題就遇到了list,map一起用的問題,3樓是問題的答案,可以參考一看。

由於map的key,value比較特殊,所以下次再說。