目录
- `<foreach>`元素
- `<bind>`元素
<foreach>
元素
MyBatis中已经提供了一种用于数组和集合循环遍历的方式,那就是使用<foreach>
元素。假设在一个用户表中有1000条数据,现在需要将id值小于100的用户信息全部查询出来,就可以通过<foreach>
元素来解决。
<foreach>
元素通常在构建IN条件语句时使用,其使用方式如下。
<!--<foreach>元素-->
<select id="findUserByIds" parameterType="List" resultType="com.ssm.po.User">
select * from t_user where id in
<foreach item="id" index="index" collection="list" open="(" separator=",“close=”)">
#{id}
</foreach>
</select>
在上述代码中,使用<foreach>
元素对传入的集合进行遍历以及动态SQL组装。关于<foreach>
元素中使用的几种属性的描述具体如下:
item:配置的是循环中当前的元素。
index:配置的是当前元素在集合中的位置下标。
collection:配置的list是传递过来的参数类型(首字母小写),可以是一个array、list(或collection)、Map集合的键、POJO包装类中的数组或集合类型的属性名等。
open和close:配置的是以什么符号将这些集合元素包装起来。
separator:配置的是各个元素的间隔符。
注意
可以将任何可迭代对象(如列表、集合等)和任何字典或者数组对象传递给作为集合参数。当使用可迭代对象或者数组时,index是当前迭代的次数,item的值是本次迭代获取的元素。当使用字典(或者MapEntry对象的集合)时,index是键,item是值。
【示例】对<foreach>
元素的使用进行测试。在测试类MybatisTest中,编写测试方法findUserByIdsTest(),其代码如下所示。
/*
*根据用户编号批量查询用户信息
*/
@Test
public void findUserByIdsTest() {
//通过工具类生成SqlSession对象
SqlSession sqlSession = MybatisUtil.getSession();
//创建List集合,封闭查询id
List<Integer> ids=new ArrayList<Integer>();
ids.add(1);
ids.add(2);
//执行SqlSession的查询办法,返回结果集
List<User> users =
sqlSession.selectList("com.ssm.mapper.UserMapper.findUserByIds",ids);
//输出查询结果
for (User user :users) {
System.out.println(user.toString());
}
sqlSession.close();
}
在上述代码中,执行查询操作时传入了一个客户编号集合ids。执行findUserByIdsTest()方法后,控制台的输出结果如图所示。从中可以看出,成功批量地查询出对应的用户信息。
在使用<foreach>
时,最关键、最容易出错的就是collection属性,该属性是必须指定的,而且在不同情况下该属性的值是不一样的,主要有以下3种情况。
- 如果传入的是单参数且参数类型是一个数组或者List的时候,collection属性值分别为array、list(或collection)。
- 如果传入的参数有多个,就需要把它们封装成一个Map,当然单参数也可以封装成Map集合,这时collection属性值就为Map的键。
- 如果传入的参数是POJO包装类,collection属性值就为该包装类中需要进行遍历的数组或集合的属性名。
在设置collection属性值的时候,必须按照实际情况配置,否则程序就会出现异常。
<bind>
元素
在进行模糊查询编写SQL语句的时候,若使用“${}”进行字符串拼接,则无法防止SQL注入问题;若使用concat函数进行拼接,则只针对 MySQL数据库有效;若使用的是Oracle数据库,则要使用连接符号“||”。这样,映射文件中的SQL就要根据不同的情况提供不同形式的实现,显然是比较麻烦的,且不利于项目的移植。为此,MyBatis提供了<bind>
元素来解决这一问题。我们完全不必使用数据库语言,只要使用 MyBatis的语言即可与所需参数连接。
MyBatis的元素可以通过OGNL表达式来创建一个上下文变量,其使用方式如下所示。
<!--<bind>元素的使用:根据用户姓名模糊查询用户信息-->
<select id="findUserByName2" parameterType="com.ssm.po.User" resultType="com.ssm.po.User">
<!--_parameter.getUsername()也可以直接写成传入的字段属性名,即username -->
<bind name="p_username" value="'%'+_parameter.getUsername()+'%'"/>
select * from t_user
where username like #{p_username}
</select>
上述配置代码中,使用<bind>
元素定义了一个name为p_username的变量,<bind>
元素中value的属性值就是拼接的查询字符串,其中_parameter.getUsername()表示传递进来的参数(也可以直接写成对应的参数变量名,如username)。在SQL语句中,直接引用<bind>
元素的name属性值即可进行动态SQL组装。
【示例】在测试类MybatisTest中,编写测试方法findUserByName2()进行测试,其代码如下所示。
/*
*根据用户姓名模糊查询用户信息
*/
@Test
public void findUserByName2() {
//通过工具类生成SqlSession对象
SqlSession sqlSession = MybatisUtil.getSession();
User user = new User();
user.setUsername("s");
//执行SqlSession的查询办法,返回结果集
List<User> users =
sqlSession.selectList("com.ssm.mapper.UserMapper.findUserByName2",user);
//输出查询结果
for (User u :users) {
System.out.println(u.toString());
}
sqlSession.close();
}
执行后,在控制台的输出结果如图所示。从中可以看出,使用MyBatis的<bind>
元素已经完成了动态SQL组装,并成功模糊查询出了用户信息。