mybatis雙重foreach如何實(shí)現(xiàn)遍歷map中的兩個(gè)list數(shù)組
實(shí)現(xiàn)背景
前端傳值時(shí)可能會(huì)有多個(gè)字段傳遞過(guò)來(lái),需要后臺(tái)將這多個(gè)字段拼接為 name in (? , ?) and name1 in (? , ?) and name2 in (? , ?) 作為sql查詢條件…
如下圖sql語(yǔ)句,即實(shí)現(xiàn)多個(gè)and xxx in(?,?,?) 拼接
select * from web_ztlc_provateequity WHERE cords in ( ? , ? , ? ) and productName in ( ? , ? , ? ) and product_id in ( ? , ? , ? )
前端傳值的格式
前端傳遞的是json字符串,json中name和infos是一對(duì)具有對(duì)應(yīng)關(guān)系的對(duì)象,且json中會(huì)有多條這種對(duì)象,即此對(duì)象是一個(gè)數(shù)組。
而infos中也會(huì)有多條數(shù)據(jù),即infos也是一個(gè)數(shù)組對(duì)象。所以最終前端傳遞過(guò)來(lái)json格式如下
json字符串:
itemList:[{"name":"cords", "infos":["2", "2222", "2223","2224","2225","2226"] },
{"name":"productName", "infos":["2號(hào)B","SAP智龍3號(hào)私募證券投資基金","一村金衍10號(hào)第1期"]}]Debug斷點(diǎn)調(diào)試java如何解析json對(duì)象
綜上所述,后臺(tái)Java接口在獲取到j(luò)son字符串后,需要遍歷json中的兩個(gè)數(shù)組對(duì)象,即name和infos
//模擬數(shù)據(jù)測(cè)試前端傳參
String itemList="[{ \"name\":\"cords\", \"infos\":[ \"2\", \"2222\", \"2223\",\"2224\",\"2225\",\"2226\" ] },{ \"name\":\"productName\", \"infos\":[ \"2號(hào)B\",\"SAP智龍3號(hào)私募證券投資基金\",\"一村金衍10號(hào)第1期\" ] }]";
//獲取前端傳過(guò)來(lái)的參數(shù)數(shù)組
//String itemList = request.getParameter("itemList");
if(!StringUtils.isEmpty(itemList)){
//將參數(shù)數(shù)組轉(zhuǎn)化為json數(shù)組類(lèi)型
JSONArray jsonArray = JSONArray.fromObject(itemList);
if(jsonArray.size()!=0){
Map<String,Object> columnMap = new HashMap<>();
//遍歷jsonarray數(shù)組
for(int i = 0;i < jsonArray.size(); i++) {
net.sf.json.JSONObject job = jsonArray.getJSONObject(i);
String name = job.getString("name");
List<String> lists =job.getJSONArray("infos");
if(lists.size()!= 0){
columnMap.put(name,lists);
}
}
hm.put("columnMap",columnMap);
}else{
return null;
}
}第一步 JSONArray.fromObject()
JSONArray jsonArray = JSONArray.fromObject(itemList);

從上圖可以看出JSONArray.fromObject(itemList)后,jsonArray已經(jīng)size=2(解析出了兩條json對(duì)象,每條對(duì)象又由name和infos各自的鍵值對(duì)(key =>value)組成,name中name為key,cords為value(這里的cords就是后面我們sql語(yǔ)句中需要拼接的and條件的字段值);
infos中的key為infos,而value又是一個(gè)數(shù)組對(duì)象(這個(gè)數(shù)組里的各個(gè)對(duì)象,就是我們后面sql語(yǔ)句中需要拼接的in的條件))

第二步 遍歷jsonArray
由第一步可以看出此時(shí)jsonArray里已經(jīng)存放了數(shù)組下標(biāo)為0和1的兩條數(shù)據(jù),那么此時(shí)我們就挨個(gè)的取出這兩條數(shù)據(jù)(也就是遍歷啦)
第一次for循環(huán)0數(shù)組,取出0數(shù)組中的name和infos,可以看出我們聲明了一個(gè)lists數(shù)組,由來(lái)存放infos中的所以數(shù)值

如下圖,我們同時(shí)還聲明了一個(gè)columnMap的Map對(duì)象,此對(duì)象用來(lái)存儲(chǔ)從json中獲取到的name和infos。
將name和infos封裝成鍵值對(duì)(key=>value)的Map對(duì)象,將來(lái)傳遞給Mybatis的parameterType="hashmap"的入?yún)傩?通過(guò)key來(lái)找value。

每次for循環(huán)就放一個(gè)鍵值對(duì)對(duì)象進(jìn)columnMap,我們這里測(cè)試數(shù)據(jù)只有兩條,所以columnMap最終會(huì)被放進(jìn)兩個(gè)鍵值對(duì)對(duì)象即columnMap的size=2.

第三步 mybatis雙重foreach
此時(shí)mybatis雙重foreach的雛形就出來(lái)了,因?yàn)閏olumnMap中已經(jīng)有2個(gè)key=>value對(duì)象了。也就意味著有多個(gè)key,而每個(gè)key又對(duì)應(yīng)多個(gè)value。所以此時(shí)mybais的foreach循環(huán)就得嵌套,第一次循環(huán)key,循環(huán)key時(shí)又得循環(huán)key對(duì)應(yīng)的多個(gè)value
最終需要foreach雙重遍歷的Map集合的數(shù)據(jù)結(jié)構(gòu)
columnMap為key的value中又存在多個(gè)key/value對(duì)象,columnMap的結(jié)構(gòu)如下

<select id="queryAllWebZtlcProvateequity" resultMap="BaseResultMap" parameterType="hashmap">
select * from web_ztlc_provateequity
<where>
<if test="columnMap != null and columnMap !=''">
<foreach item="item" collection="columnMap.entrySet()" index="key" >
and ${key} in
<foreach item="value" collection="item" open="(" close=")" separator=",">
#{value}
</foreach>
</foreach>
</if>
</where>
</select>foreach標(biāo)簽說(shuō)明
collection:需要遍歷的對(duì)象,以上代碼可以看出我寫(xiě)的是collection="columnMap.entrySet()",columnMap是我封裝的Map對(duì)象,而entrySet()則是Map的內(nèi)置方法,存儲(chǔ)的是Map中的鍵值對(duì)集合,此時(shí)第一個(gè)foreach就是在遍歷Map中的key。item:遍歷時(shí)每個(gè)元素遍歷出來(lái)時(shí)的別名,這個(gè)別名有用,我們第二次foreach是會(huì)用到,因?yàn)榈谝淮蝔oreach的是key集合,那么第二次foreach時(shí)就得遍歷key對(duì)應(yīng)的value集合。index:表示索引,也就是遍歷集合中的數(shù)組下標(biāo),0,1,2,3......等,可以看出這里我填寫(xiě)的標(biāo)簽屬性是index="key",下面and拼接時(shí)取得就是$key這個(gè)變量and ${key} inopen:in語(yǔ)句循環(huán)開(kāi)始的符號(hào),我們知道sql中in后面的條件是用()括起來(lái)的,所以這里我們填寫(xiě)的屬性是open="("close:in語(yǔ)句循環(huán)結(jié)束的符號(hào),同上,有開(kāi)始就有結(jié)束,所以這里我們填寫(xiě)的屬性是close=")"separator:多個(gè)條件拼接時(shí)的分隔符,我們知道in語(yǔ)句中會(huì)有多個(gè)條件即in(1,2,3,4)而多個(gè)條件使用逗號(hào)分割,所以這里我們填寫(xiě)的屬性是separator=","

最終效果
最后由控制臺(tái)可以看出,我們已經(jīng)成功拼接了and xxx in (?,?,?)

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
mybatis多對(duì)多關(guān)聯(lián)實(shí)戰(zhàn)教程(推薦)
下面小編就為大家?guī)?lái)一篇mybatis多對(duì)多關(guān)聯(lián)實(shí)戰(zhàn)教程(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10
java搭建一個(gè)Socket服務(wù)器響應(yīng)多用戶訪問(wèn)
本篇文章主要介紹了java搭建一個(gè)Socket服務(wù)器響應(yīng)多用戶訪問(wèn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
淺析SpringBoot及環(huán)境搭建過(guò)程
Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來(lái)簡(jiǎn)化新Spring應(yīng)用的初始搭建以及開(kāi)發(fā)過(guò)程.這篇文章主要介紹了SpringBoot介紹及環(huán)境搭建,需要的朋友可以參考下2018-01-01
Java網(wǎng)絡(luò)編程之簡(jiǎn)易聊天室的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了如何利用Java語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)易聊天室功能,可以實(shí)現(xiàn)運(yùn)行客戶端和連接服務(wù)器,文中的示例代碼講解詳細(xì),需要的可以了解一下2022-10-10
Springboot?上傳文件或頭像(MultipartFile、transferTo)
本文主要介紹了Springboot?上傳文件或頭像(MultipartFile、transferTo),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04

