mybatis中foreach的collection使用
参考:
https://blog.csdn.net/hjh908778/article/details/79034395
https://blog.csdn.net/qq_48496989/article/details/121532210
引出
mybatis的foreach主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。在实际的开发中我们使用list集合进行查询,但使用list集合范围查询时,会出现重复数据,这就需要我们使用set集合进行查询了。我在开发过程中使用set集合时,使用collection设置为set就会报错[Parameter ‘set’ not found.]。所以我重新对foreach的collection进行学习并记录。
介绍
foreach元素的属性主要有 item,index,collection,open,separator,close。
1. item : 表示集合中每一个元素进行迭代时的别名,
2. index : 指定一个名字,用于表示在迭代过程中,每次迭代到的位置,
3. collection: 指定所遍历的参数
4. open : 表示以什么开始,
5. separator : 表示在每次进行迭代之间以什么符号作为分隔 符,
6. close : 表示以什么结束。
例如:
List<Student> queryStudentList(List<String> ids);
<select id="queryStudentList" resultMap="StudentMap">
select * from student where id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
其中对于collection属性,是必填的,也是最容易出错的。不同类型状态下collection属性是不同的。
通过源码:
public static Object wrapToMapIfCollection(Object object, String actualParamName) {
MapperMethod.ParamMap map;
if (object instanceof Collection) {
map = new MapperMethod.ParamMap();
map.put("collection", object);
if (object instanceof List) {
map.put("list", object);
}
Optional.ofNullable(actualParamName).ifPresent((name) -> {
map.put(name, object);
});
return map;
} else if (object != null && object.getClass().isArray()) {
map = new MapperMethod.ParamMap();
map.put("array", object);
Optional.ofNullable(actualParamName).ifPresent((name) -> {
map.put(name, object);
});
return map;
} else {
return object;
}
}
明显得出:
- 为单个参数且参数类型为List时,collection为list
- 为单个参数且参数类型为array数组时,collection为array
- 为单个参数且参数类型为其他collection集合时,collection为collection
- 为多个参数/单个参数且参数类型为其他时,可以将参数封装为Map集合
例如
-
为单个参数且参数类型为List时,与上诉例子一致
-
为单个参数且参数类型为array数组时,collection为array
List<Student> queryStudentByArray(String[] ids);
<select id="queryStudentByArray" resultMap="StudentMap"> select * from student where id in <foreach collection="array" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </select>
-
为单个参数且参数类型为其他collection集合时,collection为collection 如set
List<Student> queryStudentBySet(Set<String> ids);
<select id="queryStudentBySet" resultMap="StudentMap"> select * from student where id in <foreach collection="collection" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </select>
-
对于单个集合参数,封装成Map集合的 collection为map集合中参数对应的key
List<Student> selectStudentByMap(Map<String,Object> paramMap);
<select id="selectStudentByMap" resultMap="StudentMap"> select * from student where id in <foreach collection="ids" item="id" index="index" open="(" separator="," close=")"> #{id} </foreach> </select>
// 使用 public List<Student> demoTest(){ List<String> idList = new ArrayList<>(); idList.add("1"); idList.add("2"); Map<String,Object> paramMap = new HashMap<>(); paramMap.put("ids",idList); List<Student> studentList = studentMapper.selectStudentByMap(); return studentList; }
-
多参数集合,封装成Map集合,collection为map集合中参数对应的key
List<Student> queryStudentByParamMap(Map<String,Object> paramMap);
<select id="queryStudentByParamMap" resultMap="StudentMap">
select * from student where name like #{name}"%" and id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</select>
// 使用
public List<Student> demoTest(){
List<String> idList = new ArrayList<>();
idList.add("1");
idList.add("2");
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("ids",idList);
paramMap.put("name","张");
List<Student> studentList = studentMapper.queryStudentByParamMap(paramMap);
return studentList;
}
最后,如果使用@Param注解,相当与将mapper中方法的参数组装成Map集合,collection属性为@Param(“key”)声明的值。
例如多参数使用@Param()与上面5对应的代码一致。
List<Student> queryStudentByParams(@Param("ids")List<String> idList, @Param("name")String name);
如果参数比较多,可以将其封装成javaBean进行传参。xml里使用直接使用javaBean的属性值。例如:
List<Student> queryStudentByParamBean(ParamsInfo params);
@Data
public class ParamsInfo{
private List<String> idList;
private String name;
}
<select id="queryStudentByParamBean" resultMap="StudentMap">
select * from student where name like #{name}"%" and id in
<foreach collection="idList" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</select>