微信搜索《Java鱼仔》,你离大厂更近了
(一)概述
mybatis官方中文网站对动态Sql的教程:mybatis.org/mybatis-3/z…
动态sql简单来讲就是我们能通过条件的设置生成不同的sql,在Mybatis中主要学习四种表达式即可:
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
(二)If
动态sql中最常见的场景是根据条件查询,比如现在我要实现一个查询语句,当不传任何参数时查询所有用户,当传了id或者name时根据条件进行查询,我就可以这样写:
<selectid="SelectUserByMap"parameterType="map"resultType="map"> select * from user where 1=1 <iftest="id != null"> and id=#{id} </if><iftest="name != null"> and name=#{name} </if></select>
通过下面的方式进行查询
Map<String,String>map=newHashMap<String, String>(); map.put("id","1"); map.put("name","javayz"); List<User>users=mapper.SelectUserByMap(map);
当map中什么都不传时,sql语句变为:
select*from user where1=1
当传了id或name时,分别执行对应的语句。
你可能会奇怪我为什么要写一个1=1,这里后面会讲到。
(三)choose、when、otherwise
choose的使用很像Java中的switch语法,当满足第一个when条件时,就不去看后续的条件,如果条件都不满足,则执行otherwise:
<selectid="SelectUserByChoose"parameterType="map"resultType="com.javayz.pojo.User"> select * from user where 1=1 <choose><whentest="id != null"> and id=#{id} </when><whentest="name != null"> and name=#{name} </when><otherwise> and 1=1 </otherwise></choose></select>
(四)trim、where、set
还记得我前面的语法中都写了where 1=1吗,至于为什么这样写,目的在于让语法能顺利执行,以if语句为例:如果不写1=1,语法就会变成下面这样
<selectid="SelectUserByMap"parameterType="map"resultType="map"> select * from user where <iftest="id != null"> id=#{id} </if><iftest="name != null"> and name=#{name} </if></select>
这个时候如果满足了第一个if条件,那不会有问题,但是如果只满足第二个条件,语句就会变成:
select*from user whereand name=?
语法直接报错。
Mybatis提供了一种标签来代替1=1的写法,where标签只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
因此上面的内容我可以改成:
<selectid="SelectUserByMap"parameterType="map"resultType="map"> select * from user <where><iftest="id != null"> and id=#{id} </if><iftest="name != null"> and name=#{name} </if></where></select>
Set的实现和where类似,我们在更新时会用到set
<updateid="UpdateUser"parameterType="map"> update user <set><iftest="name != null">name =#{name},</if></set> where id = #{id} </update>
使用where时会用自动去替换掉and或者or,而使用set时会动态地在行首插入 SET 关键字,并会删掉额外的逗号。
使用trim可以用于去除拼接sql时的and、or关键字或者逗号等等。
之前我们使用where标签去除了最开始的and关键字,用trim也同样可以实现:
<selectid="SelectUserByMap"parameterType="map"resultType="map"> select * from user <trimprefix="where"prefixOverrides="and"><iftest="id != null"> and id=#{id} </if><iftest="name != null"> and name=#{name} </if></trim></select>
去除set末尾的逗号也可以使用trim
<trimprefix="SET"suffixOverrides=","> ... </trim>
(五)foreach
foreach在需要对集合进行遍历的场景中使用很广泛,尤其是在in语句中,下面我们来实现下面这条sql语句:
select*from user where id in(1,2,3,4)
<selectid="selectUserByForeach"parameterType="map"resultType="User"> select * from user where id in <foreachcollection="ids"item="id"index="index"open="("separator=","close=")"> #{id} </foreach></select>
(六)总结
至此,我们就把mybatis的动态sql学习完毕了,总体来讲动态Sql的使用并不算复杂,关键还是多练,孰能生巧。