java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > MyBatis动态SQL解读

MyBatis之关于动态SQL解读

作者:不是很菜的菜

这篇文章主要介绍了MyBatis之关于动态SQL解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

MyBatis动态SQL

MyBatis 动态SQL优点

MyBatis 的强大特性之一便是它的动态 SQL。

如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦,拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。

利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

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>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文