对Mybatis 框架中foreach标签的collection属性取值的理解
- foreach的属性collection要求,mapper接口相应方法的参数必须是一个集合数据类型Collection,可以是其实现类或实现类的子类(ArrayList,LinkedList,HashSet,LinkedHashSet,TreeSet,HashMap,TreeMap…),也可以是数组类型。若业务传递给mybatis一个数组对象,collection的取值为"array";若业务传递给mybatis一个list集合对象,collection的取值为"list"或"collection";若业务传递给mybatis一个set集合对象,collection的取值为collection。因此可以总结一下:传递list集合和set集合都可以取值collection(这点很好理解,list集合与set集合都是Collection集合的子类)。其中传递list集合类型可以单独取值"list",但是传递set集合类型不能单独取值"set"。
<select id="selectIn" resultType="com.liwang.entity.Cart">
select * from cart where cid in
<foreach collection="collection" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</select>
<!--
<foreach collection="list" open="(" close=")" separator="," item="id">
#{id}
</foreach>
<foreach collection="array" open="(" close=")" separator="," item="id">
#{id}
</foreach>
<foreach collection="collection" open="(" close=")" separator="," item="id">
#{id}
</foreach>
-->
- mybatis框架总是会将业务传递过来的集合对象或数组对象封装到map集合中。
- 集合对象或数组对象的封装在底层可以这样理解
@Test
public void selectIn(){
CartMapper mapper = MybatisUtils.getMapper(CartMapper.class);
Integer[] ids = new Integer[]{12,13,14};
List<Integer> idList = new ArrayList<>();
Map sysMap = new HashMap<>();
sysMap.put("array", ids);//数组固定以array作为key值
sysMap.put("list", idList);//集合固定以array作为list值
sysMap.put("collection",idList);//用collection作为key再添加一次,
//当传入set体系的集合时,注意没有以set作为key值的键值对,
//set体系的集合的形式如sysMap.put("collection",idSet),如果有用Set集合存储id的话
//但是注意,mybatis没有这样做,sysMap.put("set",idSet)
List<Cart> carts = mapper.selectIn(sysMap);
System.out.printIn(carts);
}
- collection属性的所有取值实际上就是类似如上这样一个sysMap的Map对象的key值。sysMap就是Mybatis为了处理业务传递的各种查询条件与sql占位符#{key}的对应关系而在底层创建的一个map对象, 当传递多个零散的查询条件参数时使用注解@Param进行参数映射(@Param(“condition1”) Type c1,@Param(“condition2”) Type c2, …)也是以condition1,condition2, … 为键key,以c1, c2, …为值value 被Mybatis封装到一个类似sysMap的Map对象中的。
- 若你要遍历一个封装了多个查询条件的map集合对象idMap,你应该这样对idMap进行封装:
Map idMap = new HashMap();
idMap.put("one",12);
idMap.put("two",13);
idMap.put("three",14);
Map sysMap = new HashMap();
sysMap.put( "idMap" , idMap );//注意这条关键语句
List<Cart> carts = mapper.selectIn(sysMap);
- 并设置如下的collection的属性值:
<foreach collection="idMap" open="(" close=")" separator="," index="k" item="v">
#{v}
</foreach>
这样,foreach循环遍历的集合就是以"idMap"为key的sysMap集合中对应的value值,也就是第5段中被封装的名为idMap的Map对象。用一条代码可以也解释如上的foreach遍历的集合为:
sysMap.get("idMap")//这调代码的执行结果
- 如果第5段中的代码改为
Map idMap = new HashMap();
idMap.put("one",12);
idMap.put("two",13);
idMap.put("three",14);
List<Cart> carts = mapper.selectIn(idMap);
同时mapper接口的相应方法加上参数注解:
public interface CartMapper {
List<Cart> selectWithMap(@Param("idMap") Map idMap);
}
那么Mybatis会在底层做这样一件产生相同结果的事:
Map sysMap = new HashMap();
sysMap.put("idMap",idMap);