MyBatis 笔记(五)——动态 SQL

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010376788/article/details/77587887

在开发中,经常会遇到要执行的 SQL 语句其实并不是固定,而是随条件的变化而变化的。对于这种情况 MyBatis 也有解决方案。

随条件变化的 SQL

先看一个固定的 SQL 语句,查询指定 name 和 age 的人:

<resultMap id="PersonMap" type="Person">
    <id column="id" jdbcType="INTEGER" property="pid" javaType="int"/>
    <result column="name" jdbcType="VARCHAR" property="pname" javaType="String"/>
    <result column="age" jdbcType="INTEGER" property="page" javaType="int"/>
</resultMap>

<select id="selectWithNothing" parameterType="Person" resultMap="PersonMap">
    SELECT id, name, age
    FROM person
    WHERE name = #{name} and age = #{age}
</select>

上面的 SQL 当 name 或 age 为空时,该查询将会抛出异常。

if 标签

在不确定查询条件是否为空时,可以用 if 标签进行检查:

<select id="selectWithIf" parameterType="Person" resultMap="PersonMap">
    select id, name, age
    from person
    where 1=1

    <if test="pname != null and pname != '' ">
        and name = #{pname}
    </if>
    <if test="page != null and page != 0 ">
        and age &lt; #{page}
    </if>
</select>

注意:where 后的 1 = 1 建议加上,这样可以避免无一条件满足时,最终的 SQL 语句中 where 后面没有过滤条件。

调用方法如下:

public void selectWithIf(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    Person entity = new Person();
    entity.setPname("Jimmy");
    List<Person> persons = sqlSession.selectList("edu.wzm.mybatis.mapping.PersonMapper.selectWithIf", entity);

    System.out.println(persons);
    sqlSession.close();
}

where - if 标签

SELECT 语句中,为了简化 if 标签,可以使用 where - if 标签组合使用:

<select id="selectWithIfWhere" parameterType="Person" resultMap="PersonMap">
  selectid, name, age
  from person

  <where>
      <if test="pname != null and pname != '' ">
          and name = #{pname}
      </if>
      <if test="page != null and page != 0 ">
          and age &lt; #{page}
      </if>
  </where>
</select>

where - if 标签中,SQL 语句可以加上 and,MyBatis 会自动识别。

调用方法:

public void selectWithIfWhere(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    Person entity = new Person();
    entity.setPname("Jimmy");
    entity.setPage(30);
    List<Person> persons = sqlSession.selectList("edu.wzm.mybatis.mapping.PersonMapper.selectWithIfWhere", entity);

    System.out.println(persons);
    sqlSession.close();
}

set - if 标签

UPDATE 语句中,为了简化 if 标签,可以使用 set - if 标签组合使用:

<update id="updateWithIfSet" parameterType="Person">
    updateperson

    <set>
        <if test="pname != null and pname != '' ">
            name = #{pname}
        </if>
        <if test="page != null and page != 0 ">
            and age = #{page}
        </if>
    </set>

    where id = #{pid}
</update>

set 标签为自动为每个 if 标签中的 SQL 语句加上逗号隔开。

调用方法:

public void updateWithIfSet(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession(true);
    Person entity = new Person();
    entity.setPid(2);
    entity.setPname("Bill");
    int result = sqlSession.update("edu.wzm.mybatis.mapping.PersonMapper.updateWithIfSet", entity);

    System.out.println(result);
    sqlSession.close();
}

trim - if 标签

还有一种更强大的组合标签 trim - if,它既可以处理 SELECT语句,又可以处理 UPDATE 语句。如代替上面的 where - if 标签:

<select id="selectWithIfTrim" parameterType="Person" resultMap="PersonMap">
    SELECT id,name, age
    FROM person

    <trim prefix="WHERE" prefixOverrides="AND|OR">
        <if test="pname != null and pname != '' ">
            name = #{pname}
        </if>
        <if test="page != null and page != 0 ">
            age &lt; #{page}
        </if>
    </trim>
</select>

代替上面的 set - if 标签:

<update id="updateWithIfTrim" parameterType="Person">
    UPDATE person

    <trim prefix="SET" prefixOverrides=",">
        <if test="pname != null and pname != '' ">
            name = #{pname}
        </if>
        <if test="page != null and page != 0 ">
            age &lt; #{page}
        </if>
    </trim>

    WHERE id = #{pid}
</update>

choose - when 标签

上面的标签都是一组条件的中的每一个条件要么可选,要么不选。但是对于一组互斥的条件,只能从中选择一个,那么上面的标签就不好处理了,需要使用 choose - when 标签:

<select id="selectWithChooseWhen" parameterType="Person" resultMap="PersonMap">
    SELECT id, name, age
    FROM person

    <where>
        <choose>
            <when test="pname != null and pname != '' ">
                name = #{pname}
            </when>
            <when test="page != null and page != 0 ">
                AND age &lt; #{page}
            </when>
            <otherwise>

            </otherwise>
        </choose>
    </where>
</select>

注意choose - when 标签类似于 if - elseif - else

循环

对于动态 SQL 非常必须的,主是要迭代一个集合,通常是用于 IN 条件。List 实例将使用 “list” 做为键,数组实例以 “array” 做为键。

foreach 元素是非常强大的,它允许你指定一个集合,声明集合项和索引变量,它们可以用在元素体内。它也允许你指定开放和关闭的字符串,在迭代之间放置分隔符。这个元素是很智能的,它不会偶然地附加多余的分隔符。

注意:可以传递一个List实例或者数组作为参数对象传给是MyBatis。当你这么做的时候,MyBatis 会自动将它包装在一个 Map中,用名称在作为键。List 实例将会以 “list” 作为键,而数组实例将会以 “array” 作为键。

数组

使用数组实例作为参数:

<select id="selectWithForeachArray" resultMap="PersonMap">
    SELECT id, name, age
    FROM person
    WHERE id IN

    <foreach collection="array" item="pid" open="(" separator="," close=")">
      #{pid}
    </foreach>
</select>

调用方法:

public void selectWithForeachArray(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    int[] pids = {1, 3};
    List<Person> persons = sqlSession.selectList("edu.wzm.mybatis.mapping.PersonMapper.selectWithForeachArray", pids);

    System.out.println(persons);
    sqlSession.close();
}

列表

使用列表作为参数:

<select id="selectWithForeachList" resultMap="PersonMap">
    SELECT id, name, age
    FROM person
    WHERE id IN

    <foreach collection="list" item="pid" open="(" separator="," close=")">
        #{pid}
    </foreach>
</select>

调用方法:

public void selectWithForeachList(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    List<Integer> pids = new ArrayList<>();
    pids.add(2);
    pids.add(3);
    List<Person> persons = sqlSession.selectList("edu.wzm.mybatis.mapping.PersonMapper.selectWithForeachList", pids);

    System.out.println(persons);
    sqlSession.close();
}

查看完整代码

猜你喜欢

转载自blog.csdn.net/u010376788/article/details/77587887
今日推荐