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
-
drop
- createtable users (
- id int,
- namevarchar(20)
- );
- insertinto users (id, name) values(1, 'User1');
- insertinto users (id, name) values(2, 'User2');
- insertinto users (id, name) values(3, 'User3');
- insertinto users (id, name) values(4, 'User4');
-
insertinto users (id,
- insertinto users (id, name) values(6, 'User6');
Mapper.xml
- <selectid="countByUserList"resultType="_int"parameterType="list">
- select count(*) from users
- <where>
- id in
- <foreachitem="item"collection="list"separator=","open="("close=")"index="">
- #{item.id, jdbcType=NUMERIC}
- </foreach>
- </where>
- </select>
測試程式碼:
- @Test
- publicvoid shouldHandleComplexNullItem() {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- Mapper mapper = sqlSession.getMapper(Mapper.class);
- User user1 = new User();
- user1.setId(2);
- user1.setName("User2");
- List<User> users = new ArrayList<User>();
- users.add(user1);
- users.add(null);
- int count = mapper.countByUserList(users);
- Assert.assertEquals(1, count);
- } finally {
- sqlSession.close();
- }
- }
測試日誌:
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比較特殊,所以下次再說。