【Spring】— 动态SQL :<foreach>元素、<bind>元素

目录

    • ``元素
    • ``元素

元素

MyBatis中已经提供了一种用于数组和集合循环遍历的方式,那就是使用元素。假设在一个用户表中有1000条数据,现在需要将id值小于100的用户信息全部查询出来,就可以通过元素来解决。

元素通常在构建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>

在上述代码中,使用元素对传入的集合进行遍历以及动态SQL组装。关于元素中使用的几种属性的描述具体如下:

 item:配置的是循环中当前的元素。 
 index:配置的是当前元素在集合中的位置下标。 
 collection:配置的list是传递过来的参数类型(首字母小写),可以是一个array、list(或collection)、Map集合的键、POJO包装类中的数组或集合类型的属性名等。 
 open和close:配置的是以什么符号将这些集合元素包装起来。
 separator:配置的是各个元素的间隔符。

注意

可以将任何可迭代对象(如列表、集合等)和任何字典或者数组对象传递给作为集合参数。当使用可迭代对象或者数组时,index是当前迭代的次数,item的值是本次迭代获取的元素。当使用字典(或者MapEntry对象的集合)时,index是键,item是值。

【示例】对元素的使用进行测试。在测试类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()方法后,控制台的输出结果如图所示。从中可以看出,成功批量地查询出对应的用户信息。

在这里插入图片描述

在使用时,最关键、最容易出错的就是collection属性,该属性是必须指定的,而且在不同情况下该属性的值是不一样的,主要有以下3种情况。

  • 如果传入的是单参数且参数类型是一个数组或者List的时候,collection属性值分别为array、list(或collection)。
  • 如果传入的参数有多个,就需要把它们封装成一个Map,当然单参数也可以封装成Map集合,这时collection属性值就为Map的键。
  • 如果传入的参数是POJO包装类,collection属性值就为该包装类中需要进行遍历的数组或集合的属性名。

在设置collection属性值的时候,必须按照实际情况配置,否则程序就会出现异常。

元素

在进行模糊查询编写SQL语句的时候,若使用“${}”进行字符串拼接,则无法防止SQL注入问题;若使用concat函数进行拼接,则只针对 MySQL数据库有效;若使用的是Oracle数据库,则要使用连接符号“||”。这样,映射文件中的SQL就要根据不同的情况提供不同形式的实现,显然是比较麻烦的,且不利于项目的移植。为此,MyBatis提供了元素来解决这一问题。我们完全不必使用数据库语言,只要使用 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>

上述配置代码中,使用元素定义了一个name为p_username的变量,元素中value的属性值就是拼接的查询字符串,其中_parameter.getUsername()表示传递进来的参数(也可以直接写成对应的参数变量名,如username)。在SQL语句中,直接引用元素的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的元素已经完成了动态SQL组装,并成功模糊查询出了用户信息。

在这里插入图片描述

你可能感兴趣的:(Spring小知识,spring,sql,mybatis)