在www.cppcns.com做mybatis的mapper.xml檔案的時候,我們時常用到這樣的情況:動態生成sql語句的查詢條件,這個時候我們就可以用mybatis的foreach了
foreach元素的屬性主要有item,index,collection,open,separator,close。
在使用foreach的時候最關鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的,但是在不同情況下,該屬性的值是不一樣的,主要有一下3種情況:
針對最後一條,我們來看一下官方說法:
注意 你可以將乙個 list 例項或者陣列作為引數物件傳給 mybatis,當你這麼做的時候,mybatis 會自動將它包裝在乙個 map 中並以名稱為鍵。list 例項將會以「list」作為鍵,而陣列例項的鍵將是「array」。
所以,不管是多引數還是單引數的list,array型別,都可以封裝為map進行傳遞。如果傳遞的是乙個list,則mybatis會封裝為乙個list為key,list值為object的map,如果是array,則封裝成乙個array為key,array的值為object的map,如果自己封裝呢,則colloection裡放的是自己封裝的map裡的key值。
原始碼分析
由於官方文件對這塊的使用,描述的比較簡短,細節上也被忽略掉了(可能是開源專案文件一貫的問題吧),也使用不少同學在使用中遇到了問題。特別是foreach這個函式中,collection屬性做什麼用,有什麼注意事項。由於文件不全,這塊只能通過源**剖析的方式來分析一下各個屬性的相關要求。
collection屬性的用途是接收輸入的陣列或是list介面實現。但對於其名稱的要求,mybatis在實現中還是有點不好理解的,所以需要特別注意這一點。
下面開始分析源**(筆記使用的是mybatis 3.0.5版本)
先找到mybatis執行sqljxrsp配置解析的入口
mappermethod.j**a類中publicobject execute(object args)該方法是執行的入口.
針對in集合查詢,對應用就是selectforlist或selctformap方法。
但不管呼叫哪個方法,都會對原來jdk傳入的引數 object型別,通過 getparam方法轉換成乙個object,那這個方法是做什麼的呢?分析原始碼如下:
上圖中標紅的兩處,很驚訝的發現,乙個引數與多個引數的處理方式是不同的(後續很多同學遇到的問題,就有一大部分出自這個地方)。如果引數個數大於乙個,則會被封裝成map, key值如果使用了mybatis的 param註解,則會使用該key值,否則預設統一使用資料序號,從1開始。這個問題先記下,繼續分析**,接下來如果是selectforlist操作(其它操作就對應用相應方法),會呼叫defaultsqlsession的publiclistselectlist(string statement, object parameter, rowbounds rowbounds)方法
又乙個發現,見源**如下:
上圖示紅部分,對引數又做了一次封裝,我們看一下**
現在有點清楚了,如果引數型別是list,則必須在collecion中指定為list, 如果是資料組,則必須在collection屬性中指定為 array.
現在就問題就比較清楚了,如果是乙個引數的話,collection的值取決於你的引數型別。
如果是多個值的話,除非使用註解param指定,否則都是數字開頭,所以在collection中指定什麼值都是無用的。下圖是debug顯示結果。
使用方法
單引數list 型別
select count(*) from users
id in
程式設計客棧ndex="">
#
測試**:
@test
public void shouldhandlecomplexnullitem() finally
}上述collection為array,對應的mapper**:
public list dynamicforeach2test(int ids);
對應的測試**:
@public void dynamicforeach2test() ;
list blogs = blogmapper.dynamicforeach2test(ids);
for (blog blog : blogs)
system.out.println(blog);
session.close();
}3.自己把引數封裝成map的型別
select * from t_blog where title like "%"#"%" and id in
#上述collection的值為ids,是傳入的引數map的key,對應的mapper**:
public list dynamicforeach3test(map params);
對應測試**:
@test
public void dynamicforeach3test()
注意注意sql語句select * from ny_jobs where id in () 這個會報錯,所以最後判斷一下ids是有元素的
本文標題: mybatis之foreach用法詳解
本文位址:
Mybatis 示例之 foreach (下)
foreach是用來對3種型別的物件進行迴圈操作的,關於foreach的基礎知識請看 mybatis 示例之 foreach 上 注 map型別沒有預設的map,所以不能直接寫collection map 如果這麼寫,需要保證傳入的map引數有 param map 註解。有關引數的更詳細內容,建議看...
mybatis動態sql中foreach標籤的使用
foreach標籤主要用於構建in條件,他可以在sql中對集合進行迭代。如下 delete from user where id in 我們假如說引數為 int ids 那麼列印之後的sql如下 delete form user where id in 1,2,3,4,5 釋義 collection...
MyBatis中的foreach迴圈
mybatis動態sql中foreach標籤的使用 foreach標籤主要用於構建in條件,他可以在sql中對集合進行迭代。如下 delete from user where id in 我們假如說引數為 int ids 那麼列印之後的sql如下 delete form user where id ...