当传入的参数是一个集合,我们需要遍历取出集合中的每一个参数时,就需要用到foreach标签了,这里介绍它的6个常用属性:
collection:指传入可迭代(遍历)的参数的变量名称。
当传入的参数为list类型,为list当传入的参数为array类型,为array当传入的参数为map类型,为map的键key(较少使用)当传入的参数是java bean类型,那么保持和该java bean对象中支持遍历的属性的名称一致
item:迭代集合时,元素的别名index:在list和数组中,index是元素的序号,在map中,index是元素的keyopen:循环开始拼接的字符串close:循环结束拼接的字符串separator:循环中拼接的分隔符
其中collection和item参数为必填!
举个例子,多个id查询的sql语句可以写成这样
select * from user where id in (1,2,3,4)
上面的语句表示查询id为1,2,3,4的数据,那么如果在mybatis的映射文件该如何书写呢,我们总不可能直接写死这些id吧?
在
然后UserMapper.xml中的
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
对于的UserMapper接口方法如下:
public List
由于select标签的parameterType属性传入的参数是List集合,所以foreach 标签的collection属性的变量名就是小写的list。
在UserMapperTest测试类中添加测试方法进行测试:
// 同时查询多个id
@Test
public void testFindUserByIds() throws Exception {
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List
ids.add(33);
ids.add(34);
ids.add(35);
ids.add(36);
List
System.out.println(list);
}
控制台输出的结果:
假设我把foreach标签的collection属性值改成ids,再次运行就会看到这个错误:
意思就是找不到ids,可用的参数叫list。
封装传入参数
虽然parameterType的值可以直接指定具体的参数类型,但是还是建议将需要用到的参数封装到一个实体bean中,然后再把该实体bean当做输入参数来用。
还是以上面那个例子为例,我将List集合封装到一个java bean类中,例如:
public class QueryVo {
private List
public void setIds(List
this.ids = ids;
}
public List
return ids;
}
}
然后映射文件修改如下
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
对应的UserMapper接口添加一个findUserByIds2的方法
public List
注意上面映射文件中foreach 标签的collection属性值变成了ids,因为QueryVo 类中的集合属性就是ids,这2个名字是必须对应的,否则会报错,稍后会演示该错误。
在UserMapperTest测试类中添加测试方法进行测试:
// 同时查询多个id
@Test
public void testFindUserByIds2() throws Exception {
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
QueryVo queryVo = new QueryVo();
List
ids.add(10);
ids.add(16);
ids.add(22);
ids.add(24);
queryVo.setIds(ids);
List
System.out.println(list);
}
控制台输出的结果:
效果和直接传List集合的一样,但是封装后,灵活度大一点,因为我们可以将同一个业务的各种sql语句的传入参数都封装到一个java bean中进行维护。
上面提到过,如果映射文件中foreach标签的collection属性值和java bean中的集合属性名称不一样会报错,例如我将collection的属性值 ids 改成 ids2,再次运行测试代码就会看到这个错误:
意思就是在QueryVo实体类中找不到有叫ids2的属性,注意java bean规范中有getter方法的字段才能叫属性,看上图的异常也能说明这点,mybatis会去java bean中查找符合条件的getter方法,然后截取get后的方法名首字母小写就是对应的属性名,当然getter方法不是必须的,mybatis会根据collection属性值去java bean中优先找符合条件的字段名,如果找不到才会去找对应的getter方法名。
例如collection中的属性值是ids, 然后QueryVo实体类中的字段存在ids且类型是List集合类型,那么mybatis就能与之对应,无需提供getIds方法,用代码来表示就是这样的:
public class QueryVo {
private List
public void setIds(List
this.ids = ids;
}
//没有提供getIds方法也ok
}
同理,假设QueryVo实体类中ids字段的类型不是List,但是有个叫getIds的方法,且返回值是List集合类型,那么mybatis也不会报错,它也能识别,什么意思呢,用代码来表示就是这样的:
public class QueryVo {
private List
private String ids; //字段符合,但是类型不符合
public void setIds(List
this.list = ids;
}
public List
return list;
}
}
运行后,一点问题都没有,顺利通过,不过话又说回来,没有人会这么干的,一般都是按照java bean的规范来,都会提供getter方法的。