目录
Mybatis用于实现动态SQL的元素主要有:
if ,where, trim, set, choose, foreach
if标签
属性条件成立就执行,反之则不执行
//常用来做非空判断
<if test="num!=null">
num = #{num},
</if>
<if test="name=name">
name = #{name},
</if>
<if test="gender!=null">
gender = #{gender}
</if>
where标签
用于对查询条件个数不确定的情况下,<where>元素会进行判断,若果它包含的标签中返回值的话,它就插入一个where,此外,如果标签返回的内容是以 AND 或 OR 开头,它会剔除掉 AND 或 OR.
select * from teacher
<where>
<if test="name!=null">
and name = #{name}
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
</where>
trim标签
where 标签,其实用 trim 也可以表示,当 WHERE 后紧随 AND 或则 OR 的时候.就去除 AND 或者 OR.
属性 | 功能 |
---|---|
prefix | 给sql语句拼接的前缀. |
suffix | 给sql语句拼接的后缀. |
prefixOverrides | 去除sql语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定. |
suffixOverrides | 去除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定. |
prefix:
想象一下你在写作文,每次提到“我的”时候,都要写全称“我的”。但是老师告诉你,只要在文章开头说一声“下面所有的‘我的’都可以简写成‘我’”,这样你就不用每次都写完整的“我的”,直接写“我”就可以了。在 MyBatis 中,prefix
就像是这个开头的声明,它告诉 MyBatis:“下面所有的方法名前面都会有一个共同的部分,比如 ‘get’,你可以默认加上这个部分。”
prefixOverrides:
你写作文的时候,如果已经说了“下面所有的‘我的’都可以简写成‘我’”,那么你每次提到“我的书包”就可以直接写成“我书包”。这里 prefixOverrides
就像是一种规则,告诉 MyBatis:“下面这些方法名前面如果有 ‘get’,你可以把它去掉,只看后面的部分。”
简单来说,prefix就像是给你的方法名字加个前缀,让名字变长,但是一旦设定,你就不需要每次都写完整的名字了.而prefixOverrides则是让你去掉方法名字的一部分多余的前缀,使名字变短,更容易读和写.
trim标签的使用
1.当某些情况下,不适用trim标签会导致出现异常比如说,当传入num的值为空时
select * from teacher where
<if test="num!=null">
num = #{num}
</if>
<if test="name!=null">
and name = #{name}
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
查询出来的结果为
这个时候经可以用trim标签来解决这个问题,它会在去掉多余的and同时保留where
select * from teacher
<trim prefix="where" prefixOverrides="and">
<if test="num!=null">
num = #{num}
</if>
<if test="name!=null">
and name = #{name}
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
</trim>
2.trim去除逗号
当sql执行更改语句时,由于不缺定那部分的值会为空,所以有可能导致sql语句出异常
<update id="updateTeacher" parameterType="Teacher">
update teacher
<if test="num!=null">
num = #{num},
</if>
<if test="name!=null">
name = #{name},
</if>
<if test="gender!=null">
gender = #{gender}
</if>
where id = #{id}
</update>
这段代码执行的结果为
<update id="updateTeacher" parameterType="Teacher">
update teacher
<trim prefix="set" suffixOverrides=",">
<if test="num!=null">
num = #{num},
</if>
<if test="name!=null">
name = #{name},
</if>
<if test="gender!=null">
gender = #{gender}
</if>
</trim>
where id = #{id}
</update>
set标签:
去掉多余的逗号
<update id="updateTeacher" parameterType="Teacher">
update teacher
<set>
<if test="num!=null">
num = #{num},
</if>
<if test="name=name">
name = #{name},
</if>
<if test="gender!=null">
gender = #{gender}
</if>
</set>
where id = #{id}
</update>
choose标签
类似于 Java 中的 switch
语句的结构,它允许你在多个条件之间选择一个来执行.当你需要根据不同的条件执行不同的 SQL 片段时,<choose>
标签是非常有用的.
select * from teacher
<trim prefix="where" prefixOverrides="and|or">
<choose>
<when test="name!=null">
and name = #{name}
</when>
<otherwise>/*otherwise只能有一个*/
name = '李老师'
</otherwise>
</choose>
</trim>
当name的值为空的时候会执行<otherwise>标签里的语句,并且otherwise只能有一个<when>能有多个
foreach标签
用于迭代集合数据的动态 SQL 处理器.它可以遍历数组,列表或 Map 对象中的集合值,主要用在构建 in 条件中.
foreach中有五个参数:
collection:指定的集合变量名 可以是数组Array[],Arraylist和map类型
separator:定义了每次迭代之间的分隔符
item:当前项目的别名,可以在<foreach> 内部使用这个别名来引用当前迭代的元素.
open:定义循环的开始符号
close:定义了循环的结束符号
1.循环查询
select id="findTeacher" resultType="com.ffyc.mybatispro.model.Teacher">
select
<foreach item="col" collection="list" separator=","> //list ---> 传入的类型是数组
${col}
</foreach>
from teacher
</select>
2.循环删除
<delete id="deleteTeacher">
delete from teacher where id in
//collection传入的是数组
<foreach collection="array" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
${}和#{}的区别
#{} 是占位符,是采用预编译方式向sql传值,可以防止sql注入,如果我们在sql中传值,使用#{}
${} 是将内容直接拼接到sql语句中,一般不用于向sql中传值,一般用于向sql动态传递列名区别:
底层实现不同
#{} 采用预编译方式,防止sql注入更加安全
${} 采用字符拼接,直接将值拼接到sql中
使用场景
#{} 一般用于向sql中的传值
${} 一般用于向sql动态传递列名 例如 排序时 order by 后面的列名是可以改变的
select 后面的列名也可以自由选择
特殊符号处理
在 mybatis 中的 xml 文件中,存在一些特殊的符号,比如:、"、&、<> 等,正常书写 mybatis 会报错,需要对这些符号进行转义。具体转义如下所示:
< | < |
> | > |
" | " |
' | ' |
& | & |
除了可以使用上述转义字符外,还可以使用来<![CDATA[ ]]>包裹特殊字符。如下所示
<if test="id != null">
AND <![CDATA[ id <> #{id} ]]>
</if>
<![CDATA[ ]]是 XML 语法。在 CDATA 内部的所有内容都会被解析器忽略。 但是有个问题那就是 等这些标签都不会被解析,所以 我们只把有特殊字符的语句放在 尽量缩小的范围