目录
[3、choose 、when 、otherwise元素](#3、choose 、when 、otherwise元素)
[4、trim 、where 、set 元素](#4、trim 、where 、set 元素)
1、动态SQL
打个比方说,我们在网站上查询一个手机,他会有很多的选项,比如品牌、内存、处理器、年份等等。这就好比我们sql语句中的查询操作,select * from 手机表 where 品牌 and 内存 and 处理器 等等。但是在我们用MyBaits写映射器处理sql语句时是固定的查询,这就导致我们的代码是硬代码。就好比下方代码:
XML
<select id = "findStudentByClassidAndSsex" parameterType="student" resultType="student">
select * from student where classid = #{classid} and ssex = #{ssex}
</select>
这里就只能查询规定班级号和性别的学生,但是如果我想要通过学生id查看或者通过学生生日查询的话就还得再去写新的映射器,这样就会造成代码冗余。
(1)什么是动态SQL?
定义:根据不同条件拼接SQL语句,实现对数据库更准确的操作;
实现:映射器配置文件或者注解。
(2)常用的动态SQL元素
|--------------------------|-------------------------|
| if 元素 | 判断语句,单条件分支判断. |
| choose元素(when,otherwise) | 多条件分支判断,等同于java的switch. |
| trim(where,set) | 辅助元素,用于处理一些 SQL 拼接的问题. |
| foreach 元素 | 循环语句,在 in 语句等列举条件常用 |
2、if元素
语法: < if test ="条件"> 满足条件的语句
注意:拼接 SQL 语句的时候注意 AND 和逗号
示例代码:
XML
<select id = "findStudent" parameterType="student" resultType="student">
select * from student where 1=1
<if test="classid != 0">
and classid = #{classid}
</if>
<if test="ssex != null">
and ssex = #{ssex}
</if>
</select>
可以添加多条if来实现动态查询,加上一个if就会多一层判断。
3、choose 、when 、otherwise元素
(1)为什么使用choose元素
choose相当于java中 switch 结构,条件有先后顺序,越优先先写,一旦匹配到,后面的条件就不会再执行。
场景1:当新闻编号不为空,则只用新闻编号作为查询条件;
场景2:当新闻编号为空,而新闻标题不为空,则用新闻标题作为条件进行模糊查询;
场景3:当新闻编号和新闻标题都为空,则要求新闻作者不能为空。
(2)choose元素的功能
语法:
XML
<choose>
<when test="条件">满足条件的语句</ when>
<otherwise> 满足其他条件的语句 <otherwise>
</choose>
注意:
- 拼接 SQL 语句的时候注意 AND 和逗号
- when 标签自带break
- otherwise 标签当所有的when都不匹配时才会执行,相当于 default、else 可以不写。
4、trim 、where 、set 元素
前言:if语句中如果没有匹配上的话就拼接后的sql语句就变成了select * from 表名 where了。
所以就有了trim、where、set元素的出现。
(1)什么是where元素
示例代码:
XML
<select id = "findStudentWhere" parameterType="student" resultType="student">
<include refid="stusql"></include>
<where>
<if test="classid != 0">
and classid = #{classid}
</if>
<if test="ssex != null">
and ssex = #{ssex}
</if>
</where>
</select>
注意:当前没有任何条件的时候,不会添加where关键字 有条件的时候会添加一个where关键字、去掉第一个and关键字。
(2)什么是set元素
示例代码:
XML
<update id="updateStudentSet" parameterType="student">
update student
<set>
<if test="sname != null">
sname = #{sname},
</if>
<if test="birthday != null">
birthday = #{birthday},
</if>
<if test="ssex != null">
ssex = #{ssex},
</if>
<if test="classid != null">
classid = #{classid},
</if>
</set>
<where>
sid = #{sid}
</where>
</update>
相当于sql语句添加set关键字,而且会去掉最后一个逗号。
(3)什么是trim元素
前言:where子句的 and 和 or、set 子句的逗号,就算set能去除逗号,呢也是最后一个逗号,前面的语句中的逗号也十分的难缠,这时候我们就可以用trim万能标签来解决这一问题。
- prefix:需要往前拼接的子句,可以是 where,or 或者 set;(开始前添加一个什么)
- suffix:需要往后拼接的子句,可以是 where,or 或者 set;(结束后添加一个什么)
- suffixOvrrides:忽略通过管道分隔的文本序列后缀。一般不与 prefixOvrrides 同时使用。(结束后去掉一个什么)
- prefixOvrrides:忽略通过管道分隔的文本序列前缀。一般不与 suffixOvrrides 同时使用。(开始前去掉一个什么)
示例代码:
XML
<update id="updateStudentTrim" parameterType="student">
update student
<trim prefix="set" suffixOverrides=",">
<if test="sname != null">
sname=#{sname},
</if>
<if test="birthday != null">
birthday=#{birthday},
</if>
<if test="ssex != null">
ssex=#{ssex},
</if>
<if test="classid != 0">
classid=#{classid},
</if>
</trim>
<trim prefix="where" prefixOverrides="and">
and sid = #{sid}
</trim>
</update>
5、foreach元素
前言:
如果sql语句中的条件判断太多太复杂,呢这时候有没有一个公式可以让我们拼接呢。 这时候就可以用foreach元素来拼接。
(1)什么是foreach元素
|------------|---------------------|
| item | 循环中的当前元素; |
| index | 当前循环元素的位置下标; |
| collection | 方法传递的参数,一个数组或者集合; |
| open | 以什么符号开始将这些集合元素包装起来; |
| close | 以什么符号结束将这些集合元素包装起来; |
| separator | 各个元素的间隔符号。 |
示例代码: (clollection 如果是数组传array,如果List结合传list)
array数组:
XML
<select id="findStudentArray" resultType="student" >
<include refid="stusql"/>
<where>
<foreach collection="array" item="x" open="sid in (" close=")" separator=",">
#{x}
</foreach>
</where>
</select>
list列表:
XML
<select id="findStudentList" resultType="student" >
<include refid="stusql"/>
<where>
<foreach collection="list" item="x" open="sid in (" close=")" separator=",">
#{x}
</foreach>
</where>
</select>
6、bind元素
前言:
通配符比如模糊查询会给SQL语句拼接增加难度,因为拼接中的%号为字符串。 呢bind元素就可以解决这个问题。
(1)什么是bind元素
- name:自定义变量的变量名。
- value:自定义变量的变量值。
- _parameter:传递进来的参数。
解决模糊查询:
方案一(concat()拼接):
XML
select * from student where sname like concat('%',#{value},'%')
方案二(sql语法):
XML
select * from student where sname like "%"#{value}"%"
方案三(${}不推荐):
XML
select * from student where sname like ${%}#{value}${%}
${} 字符串的替换 不能防止SQL注入
方案四(bind强烈推荐):
XML
<bind name="keyn" value="'%'+_parameter+'%'"/>
select * from student where sname like #{keyn}
注意:bind是用来定义变量。