MyBatis 动态SQL

MyBatis 动态SQL优点

MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦,拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

1. if
2. choose (when, otherwise)
3. trim (where)
4. foreach
5. bind(不常用)

1、if

动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分,例如

<select id="getByDept"  resultType="City">
        select * from provice
        <where>
               <if test="pid!=null">
                    pid=#{pid} 
                </if>
        </where>
    </select>

        当满足if中的条件是就会把if中条件也加入进sql语句中,否则不会。例如当pid不能与null时,就会查找provice表中pid为传入的值的数据,但是当pid=null时,就会查找provice表中的所有数据。

2、choose (when, otherwise)
        有些时候你并不想用到所有条件,但是有时候你又想用到这个条件,这个时候我们就可以用到choose(when,otherwise),这类似于java中的switch-case。
<select id="findStudentByChoose" resultType="City">
        SELECT * from city where 1=1
        <choose>
            <when test="cname!=null and cname!=''">
                and cname like concat(concat('%',#{cname}),'%')
            </when>
            <when test="pid!=0">
                and pid=#{pid}
            </when>
            <otherwise>
				<!-- 这里可以写,也可以不写代码-->
            </otherwise>
        </choose>
    </select>

        这里提供了两种选择方式,你可以选择根据cname来查找,也可以选择根据pid来查找,但只要满足一个条件,其他条件则自动选择不满足,这样也可以避免无意义的查找。(上面的1=1也可以不写,但是需要加入其他的东西,下面会提到)

3、trim(where)

前面例子已经合宜地解决了动态 SQL 问题,但是看下面的例子

<select id="getByDept"  resultType="City">
        select * from provice where
               <if test="pid!=null">
                    pid=#{pid} and
                </if>
                <if test="cname!=null and cname!=''">
                    and pname like concat(concat('%',#{cname}),'%')
               </if>
    </select>

当没有一个条件满足时,这会变成

select * from provice where

这样的sql语句并不正确,另外当第一个条件不满足,第二个条件满足时则会变成

select * from provice where
and pname like concat(concat('%',#{cname}),'%')

这个查询也会失败。这个问题不能简单的用条件句式来解决,这个时候我们就可以选择使用trim(where)

<select id="getByDept"  resultType="City">
        select * from provice where
            <trim suffix="" suffixOverrides="and">
               <if test="pid!=null">
                    pid=#{pid} and
                </if>
                <if test="cname!=null and cname!=''">
                    and pname like concat(concat('%',#{cname}),'%')
               </if>
            </trim>
    </select>

where 元素知道只有在一个以上的if条件有值的情况下才去插入"WHERE"子句。而且,若最后的内容是"AND"或"OR"开头的,where 元素也知道如何将他们去除。

如果 where 元素没有按正常套路出牌,我们还是可以通过自定义 trim 元素来定制我们想要的功能。

4、foreach

动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN 条件语句的时候。
注意 你可以将一个 List 实例或者数组作为参数对象传给 MyBatis,当你这么做的时候,MyBatis 会自动将它包装在一个 Map 中并以名称为键。List 实例将会以"list"作为键,而数组实例的键将是"array"。
例如

<!--根据数组来找-->
    <select id="findStudentByArray" resultType="City">
        SELECT * from city where pid in 
        <foreach collection="array" item="pid" open="(" separator="," close=")">
            #{pid}
        </foreach>
    </select>

    <!--根据列表来找-->
    <select id="findStudentByList" resultType="City">
        select * from city WHERE pid in
        <foreach collection="list" item="pid" open="(" separator="," close=")">
            #{pid}
        </foreach>
    </select>

    <!--根据map来找-->
    <select id="findStudentByMap" resultType="City">
        SELECT * from city where cname like concat(concat('%',#{cname}),'%') and pid in
        				<!--这里的name则根据前面传入的key值来确定-->
        <foreach collection="name" item="map" open="(" separator="," close=")">
            #{map}
        </foreach>
    </select>
5、bind

bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。例如

<select id="bind" resultType="Provice">
  <bind name="pro" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM porvice
  WHERE pid LIKE #{pro}
</select>

你可能感兴趣的:(mybatis)