151. Spring Boot MyBatis升级篇-XML-动态SQL(if test)

 

【视频 & 交流平台】

à SpringBoot视频

http://study.163.com/course/introduction.htm?courseId=1004329008&utm_campaign=commission&utm_source=400000000155061&utm_medium=share

à SpringCloud视频

http://study.163.com/course/introduction.htm?courseId=1004638001&utm_campaign=commission&utm_source=400000000155061&utm_medium=share

à Spring Boot源码

https://gitee.com/happyangellxq520/spring-boot

à Spring Boot交流平台

http://412887952-qq-com.iteye.com/blog/2321532

 

 

需求缘起

       对于XML配置方法大家比较熟悉,为了文章系列的完整性,在这里也简单的介绍下。

 

本章的大纲:

(1)if标签
(2)if+where的条件判断
(3)if+set的更新语句
(4)if+trim代替where/set标签
(5)choose (when, otherwise)
(6)foreach

 

 

       接下来看下具体的内容:

1if标签

if标签可用在许多类型的sql语句中,我们以查询为例。首先看一个很普通的查询:

     <select id="select1" resultMap="baseResultMap">
        select *from demo where
           name = #{name} and email = #{email}
     </select>

 

但是此时如果nameemailnull,此语句很可能报错或查询结果为空。此时我们使用if动态sql语句先进行判断,如果值为null或等于空字符串,我们就不进行此条件的判断,增加灵活性。

DemoMapper的代码很简单:

/**test if */
public List<Demo> select1(Demo demo);

 

       Demo.xml代码修改为使用if test

<select id="select1" resultMap="baseResultMap">
        select *from demo where
           <if test="name != null and name != ''">
               name = #{name}   
           </if>
           <if test="email != null and email != ''">
               and email=#{email}
           </if>
 </select>

 

       访问http://127.0.0.1:8080/select1?name=王五 能正常访问,

但是如果访问:

http://127.0.0.1:8080/select1 或者 http://127.0.0.1:8080/[email protected]

一运行就报错了。这时候where标签就出现了,所以技术就有存在的道理。

 

2if+where的条件判断

where中的条件使用的if标签较多时,这样的组合可能会导致错误。上面的查询语句中,当访问:http://127.0.0.1:8080/[email protected] 参数namenull,将不会进行name列的判断,则会直接导“WHERE AND”关键字多余的错误SQL

       这时我们可以使用where动态语句来解决。这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where。此外,如果标签返回的内容是以AND OR 开头的,则它会剔除掉。

       上面的<select>修改为如下:

<select id="select1" resultMap="baseResultMap">
        select *from demo
           <where>
               <if test="name != null and name != ''">
                   name = #{name}   
               </if>
               <if test="email != null and email != ''">
                   and email=#{email}
               </if>
           </where>
 </select>

 

       此时访问的话,会构造不同的SQL语句:

访问1http://127.0.0.1:8080/select1

select *from demo

访问2http://127.0.0.1:8080/select1?name=王五 

select *from demo WHERE name = ?

访问3http://127.0.0.1:8080/[email protected] 

select *from demo WHERE email=?

访问5http://127.0.0.1:8080/select1?name=王五&[email protected]

select *from demo WHERE name = ? and email=?

       都非常的完美。

 

3if+set的更新语句

update语句中没有使用if标签时,如果有一个参数为null,都会导致错误。

当在update语句中使用if标签时,如果前面的if没有执行,则会导致逗号多余错误。使用set标签可以将动态的配置SET 关键字,和剔除追加到条件末尾的任何不相关的逗号

使用if+set标签修改后,如果某项为null则不进行更新,而是保持数据库原值。如下示例:

<update id="update1">
       update demo
           <set>
               <if test="name != null and name != ''">
                   name = #{name},
               </if>
               <if test="email != null and email != ''">
                    email=#{email}
               </if>
           </set>
       where id =  #{id}
</update>

 

       这样就可以单独修改name或者email,或者是同时修改nameemail,但是需要注意,如果什么都不修改的话是会报错的。

 

4if+trim代替where/set标签

trim是更灵活的去处多余关键字的标签,它可以实践whereset的效果。

4.1trim 代替where

 

   <select id="select2" resultMap="baseResultMap">
        select *from demo
           <trim prefix="where" prefixOverrides="and|or">
               <if test="name != null and name != ''">
                   name = #{name}   
               </if>
               <if test="email != null and email != ''">
                   and email=#{email}
               </if>
           </trim>
    </select>

 

 

4.1trim 代替set

   <update id="update2">
       update demo
           <trim prefix="set" suffixOverrides=",">
               <if test="name != null and name != ''">
                   name = #{name},
               </if>
               <if test="email != null and email != ''">
                    email=#{email}
               </if>
           </trim>
       where id =  #{id}
    </update>

 

 

5choose (when, otherwise)

有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。而使用if标签时,只要test中的表达式为true,就会执行if标签中的条件。MyBatis提供了choose 元素。if标签是与(and)的关系,而choose标签是或(or)的关系

       choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则choose结束。当choose中所有when的条件都不满则时,则执行otherwise中的sql类似于Java switch 语句chooseswitchwhencaseotherwise则为default

       例如下面例子,同样把所有可以限制的条件都写上,方面使用。choose会从上到下选择一个when标签的testtruesql执行。安全考虑,我们使用wherechoose包起来,放置关键字多于错误。

    <select id="select3" resultMap="baseResultMap">
        select *from demo
           <where>
               <choose>
                  <when test="name != null and name != ''">
                      name = #{name}   
                  </when>
                  <when test="email != null and email != ''">
                      and email=#{email}
                   </when>
                   <otherwise>
                     
                   </otherwise>
               </choose>
           </where>
    </select>

 

访问测试:

访问1http://127.0.0.1:8080/select3

select *from demo

访问2http://127.0.0.1:8080/select3?name=王五  

select *from demo where name = ?

访问3http://127.0.0.1:8080/[email protected]

select *from demo WHERE email = ?

访问4http://127.0.0.1:8080/select3?name=王五&[email protected]

select *from demo WHERE name = ?

       这里满足了name != null and name != ''的条件,所以条件就是name=?

 

6foreach

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

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

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

 

6.1)参数为array示例的写法

       接口方法的声明:

/**foreach: 参数为array示例的写法*/
public List<Demo> select3(String[] ids);

 

 

       动态SQL语句:

    <select id="select4" resultMap="baseResultMap">
        select *from demo where id in
           <foreach collection="array" item="id" open="(" separator="," close=")">
               #{id}
           </foreach>
    </select>

 

 

6.2)参数为List示例的写法

       接口方法声明:

/**foreach: 数为list示例的写法*/
public List<Demo> select5(List<Integer> list);

 

动态SQL语句:

<select id="select5" resultMap="baseResultMap">
        select *from demo where id in
           <foreach collection="list" item="id" open="(" separator="," close=")">
               #{id}
           </foreach>
</select>

 

 

视频&交流平台

à SpringBoot网易云课堂视频

http://study.163.com/course/introduction.htm?courseId=1004329008

à Spring Boot交流平台

http://412887952-qq-com.iteye.com/blog/2321532

 

 

 

 

猜你喜欢

转载自412887952-qq-com.iteye.com/blog/2393436