请选择 进入手机版 | 继续访问电脑版
MSIPO技术圈 首页 IT技术 查看内容

mybatis双重foreach实现遍历map中的两个list数组

2023-07-13

实现背景:

前端传值时可能会有多个字段传递过来,需要后台将这多个字段拼接为 name in (? , ?) and name1 in (? , ?) and name2 in (? , ?) 作为sql查询条件…如下图sql语句,即实现多个and xxx in(?,?,?) 拼接

select * from web_ztlc_provateequity WHERE
 cords in ( ? , ? , ?  ) 
 and productName in ( ? , ? , ? ) 
 and product_id in ( ? , ? , ? )

前端传值的格式

前端传递的是json字符串,json中name和infos是一对具有对应关系的对象,且json中会有多条这种对象,即此对象是一个数组。而infos中也会有多条数据,即infos也是一个数组对象。所以最终前端传递过来json格式如下

json字符串:
itemList:[{"name":"cords", "infos":["2", "2222", "2223","2224","2225","2226"] },
          {"name":"productName", "infos":["2号B","SAP智龙3号私募证券投资基金","一村金衍10号第1期"]}]

Debug断点调试java如何解析json对象

综上所述,后台Java接口在获取到json字符串后,需要遍历json中的两个数组对象,即name和infos

		//模拟数据测试前端传参
		String itemList="[{ \"name\":\"cords\", \"infos\":[ \"2\", \"2222\", \"2223\",\"2224\",\"2225\",\"2226\" ] },{ \"name\":\"productName\", \"infos\":[ \"2号B\",\"SAP智龙3号私募证券投资基金\",\"一村金衍10号第1期\" ] }]";
		//获取前端传过来的参数数组
        //String itemList = request.getParameter("itemList");
		if(!StringUtils.isEmpty(itemList)){
			//将参数数组转化为json数组类型
			JSONArray jsonArray = JSONArray.fromObject(itemList);
			if(jsonArray.size()!=0){
				Map<String,Object> columnMap = new HashMap<>();
 				//遍历jsonarray数组
				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已经size=2(解析出了两条json对象,每条对象又由name和infos各自的键值对(key =>value)组成,name中name为key,cords为value(这里的cords就是后面我们sql语句中需要拼接的and条件的字段值);infos中的key为infos,而value又是一个数组对象(这个数组里的各个对象,就是我们后面sql语句中需要拼接的in的条件))
在这里插入图片描述

第二步 遍历jsonArray

由第一步可以看出此时jsonArray里已经存放了数组下标为0和1的两条数据,那么此时我们就挨个的取出这两条数据(也就是遍历啦)
第一次for循环0数组,取出0数组中的name和infos,可以看出我们声明了一个lists数组,由来存放infos中的所以数值
在这里插入图片描述

如下图,我们同时还声明了一个columnMap的Map对象,此对象用来存储从json中获取到的name和infos。将name和infos封装成键值对(key=>value)的Map对象,将来传递给Mybatis的parameterType="hashmap"的入参属性,通过key来找value。
在这里插入图片描述
每次for循环就放一个键值对对象进columnMap,我们这里测试数据只有两条,所以columnMap最终会被放进两个键值对对象即columnMap的size=2.
在这里插入图片描述

第三步 mybatis双重foreach

此时mybatis双重foreach的雏形就出来了,因为columnMap中已经有2个key=>value对象了。也就意味着有多个key,而每个key又对应多个value。所以此时mybais的foreach循环就得嵌套,第一次循环key,循环key时又得循环key对应的多个value

最终需要foreach双重遍历的Map集合的数据结构
columnMap为key的value中又存在多个key/value对象,columnMap的结构如下
在这里插入图片描述

<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标签说明

collection:需要遍历的对象,以上代码可以看出我写的是collection="columnMap.entrySet()",columnMap是我封装的Map对象,而entrySet()则是Map的内置方法,存储的是Map中的键值对集合,此时第一个foreach就是在遍历Map中的key。

item:遍历时每个元素遍历出来时的别名,这个别名有用,我们第二次foreach是会用到,因为第一次foreach的是key集合,那么第二次foreach时就得遍历key对应的value集合。

index:表示索引,也就是遍历集合中的数组下标,0,1,2,3......等,可以看出这里我填写的标签属性是index="key",下面and拼接时取得就是$key这个变量and ${key} in

open:in语句循环开始的符号,我们知道sql中in后面的条件是用()括起来的,所以这里我们填写的属性是open="("

close:in语句循环结束的符号,同上,有开始就有结束,所以这里我们填写的属性是close=")"

separator:多个条件拼接时的分隔符,我们知道in语句中会有多个条件即in(1,2,3,4)而多个条件使用逗号分割,所以这里我们填写的属性是separator=","

在这里插入图片描述

最终效果

最后由控制台可以看出,我们已经成功拼接了and xxx in (?,?,?)
在这里插入图片描述

相关阅读

热门文章

    手机版|MSIPO技术圈 皖ICP备19022944号-2

    Copyright © 2024, msipo.com

    返回顶部