Mybatis动态SQL,你真的会了吗?,Java面试题中高级

  and bed_num=#{bedNum}



[](

)choose、when、otherwise

----------------------------------------------------------------------------------------



有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。



还是上面的例子改变一下:此时只能满足一个筛选条件,如果前端传来住院号就只按照住院号查找,如果传来床位号就只按照床位号筛选,如果什么都没传,就筛选所有在院的。此时的查询如下:



<select id="selectPats"

 resultType="com.xxx.domain.PatientInfo">

select * from patient_info where 1=1

<!--住院号不为null时,根据住院号查找-->

<when test="iptNum != null">

  AND ipt_num=#{iptNum}

</when>

<!--床位号不是NUll-->

<when test="bedNum != null">

  AND bed_num = #{bedNum}

</when>

<otherwise>

  AND status=1

</otherwise>



MyBatis 提供了 choose 元素,按顺序判断 when 中的条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的 sql。类似于 Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为default。



[](

)where

------------------------------------------------------------------------



举个栗子:对于choose标签的例子中的查询,如果去掉where后的1=1此时的SQL语句会变成什么样子,有三种可能的SQL,如下:



select * from patient_info where AND ipt_num=#{iptNum};

select * from patient_info where AND bed_num = #{bedNum};

select * from patient_info where AND status=1;




发生了什么,以上三条SQL语句对吗?很显然是不对的,显然where后面多了个AND。如何解决呢?此时就要用到where这个标签了。



where 元素只会在子元素返回任何内容的情况下才插入 WHERE 子句。而且,若子句的开头为 AND 或 OR,where 元素也会将它们去除。



此时的查询改造如下:



<select id="selectPats"

 resultType="com.xxx.domain.PatientInfo">

select * from patient_info

<where>

    <choose>

      <!--住院号不为null时,根据住院号查找-->

      <when test="iptNum != null">

        AND ipt_num=#{iptNum}

      </when>

      <!--床位号不是NUll-->

      <when test="bedNum != null">

        AND bed_num = #{bedNum}

      </when>

      <otherwise>

        AND status=1

      </otherwise>

    </choose>



[](

)foreach

--------------------------------------------------------------------------



foreach是用来对集合的遍历,这个和Java中的功能很类似。通常处理SQL中的in语句。



foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符



你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。



例子如下:






改标签中的各个属性的含义如下:  

![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20201222143259822.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80OTUyNzMzNA==,size_16,color_FFFFFF,t_70)



[](

)set

----------------------------------------------------------------------



讲这个标签之前,先看下面这个例子:



UPDATE STUDENT

SET NAME = #{name},

MAJOR = #{major},

HOBBY = #{hobby}

WHERE ID = #{id};
UPDATE STUDENT SET

<if test="name!=null and name!='' ">

    NAME = #{name},

</if>

<if test="hobby!=null and hobby!='' ">

    MAJOR = #{major},

</if>

<if test="hobby!=null and hobby!='' ">

    HOBBY = #{hobby}

</if>

WHERE ID = #{id};


## 总结

总的来说,面试是有套路的,一面基础,二面架构,三面个人。

**最后,小编这里收集整理了一些资料,其中包括面试题(含答案)、书籍、视频等。希望也能帮助想进大厂的朋友**

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](https://ali1024.coding.net/public/P7/Java/git)**

![三面蚂蚁金服成功拿到offer后,他说他累了](https://upload-images.jianshu.io/upload_images/24616006-89408af727026415?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![三面蚂蚁金服成功拿到offer后,他说他累了](https://upload-images.jianshu.io/upload_images/24616006-04efb6acbae62bd3?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
上一篇:【题解】CF1278F Cards / P6031 Cards 加强版


下一篇:[bzoj4971]记忆中的背包