四、Mybatis多id查询之foreach标签的使用

当传入的参数是一个集合,我们需要遍历取出集合中的每一个参数时,就需要用到foreach标签了,这里介绍它的6个常用属性:

  • collection:指传入可迭代(遍历)的参数的变量名称。
    • 当传入的参数为list类型,为list
    • 当传入的参数为array类型,为array
    • 当传入的参数为map类型,为map的键key(较少使用)
    • 当传入的参数是java bean类型,那么保持和该java bean对象中支持遍历的属性的名称一致
  • item:迭代集合时,元素的别名
  • index:在list和数组中,index是元素的序号,在map中,index是元素的key
  • open:循环开始拼接的字符串
  • close:循环结束拼接的字符串
  • separator:循环中拼接的分隔符

其中collection和item参数为必填!

举个例子,多个id查询的sql语句可以写成这样

select * from user  where id in (1,2,3,4)

上面的语句表示查询id为1,2,3,4的数据,那么如果在mybatis的映射文件该如何书写呢,我们总不可能直接写死这些id吧?

标签体内的sql语句就可以这样书写了:





<mapper namespace="blog.csdn.net.mchenys.mapper.UserMapper">

	
	<select id="findUserByIds" parameterType="java.util.List" 
		resultType="blog.csdn.net.mchenys.poj.User">
		
		select * from user 
		<where>
			<if test="list != null">
				
				<foreach collection="list" item="id" open="id in(" close=")" separator=",">
					#{id}
				foreach>
			if>
		where>
	select>

mapper>

对于的UserMapper接口方法如下:

public List<User> findUserByIds(List<Integer> 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<Integer> ids = new ArrayList<Integer>();
	ids.add(33);
	ids.add(34);
	ids.add(35);
	ids.add(36);

	List<User> list = mapper.findUserByIds(ids);

	System.out.println(list);
}

控制台输出的结果:
在这里插入图片描述
假设我把foreach标签的collection属性值改成ids,再次运行就会看到这个错误:
四、Mybatis多id查询之foreach标签的使用_第1张图片
意思就是找不到ids,可用的参数叫list。

封装传入参数

虽然parameterType的值可以直接指定具体的参数类型,但是还是建议将需要用到的参数封装到一个实体bean中,然后再把该实体bean当做输入参数来用。

还是以上面那个例子为例,我将List集合封装到一个java bean类中,例如:

public class QueryVo {
	
	private List<Integer> ids;

	public void setIds(List<Integer> ids) {
		this.ids = ids;
	}

	public List<Integer> getIds() {
		return ids;
	}
}

然后映射文件修改如下





<mapper namespace="blog.csdn.net.mchenys.mapper.UserMapper">

	
	<select id="findUserByIds2" parameterType="blog.csdn.net.mchenys.poj.QueryVo" 
		resultType="blog.csdn.net.mchenys.poj.User">
		
		select * from user 
		<where>
			<if test="ids != null">
				
				<foreach collection="ids" item="id" open="id in(" close=")" separator=",">
					#{id}
				foreach>
			if>
		where>
	select>

mapper>

对应的UserMapper接口添加一个findUserByIds2的方法

public List<User> findUserByIds2(QueryVo vo);

注意上面映射文件中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<Integer> ids = new ArrayList<Integer>();
	ids.add(10);
	ids.add(16);
	ids.add(22);
	ids.add(24);
	queryVo.setIds(ids);

	List<User> list = mapper.findUserByIds2(queryVo);

	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<Integer> ids;//字段名是ids,且类型是List集合就符合条件了

	public void setIds(List<Integer> ids) {
		this.ids = ids;
	}
	
	//没有提供getIds方法也ok
	
}

同理,假设QueryVo实体类中ids字段的类型不是List,但是有个叫getIds的方法,且返回值是List集合类型,那么mybatis也不会报错,它也能识别,什么意思呢,用代码来表示就是这样的:

public class QueryVo {
	
	private List<Integer> list;
	
	private String ids; //字段符合,但是类型不符合

	public void setIds(List<Integer> ids) {
		this.list = ids;
	}

	public List<Integer> getIds() {  //存在getter方法,且参类型符合也ok
		return list;
	}
}

运行后,一点问题都没有,顺利通过,不过话又说回来,没有人会这么干的,一般都是按照java bean的规范来,都会提供getter方法的。

你可能感兴趣的:(Mybatis)