Mybatis学习--15.动态SQL
动态SQL
为什么需要动态SQL
- 学习新技术前我们需要知道为什么需要学习这个技术,即这项技术有什么用,在我们的开发过程中有哪些场景可以用到?
- 我们之前的SQL语句要么是静态的,要么是可以预测的(参数固定的)。但在实际应用中在很多场景下,sql语句并不是固定的。比如:批量删除功能,我们无法预测用户需要删除多少数据,因此我们无法提前编写好sql语句。再比如:用户指定多个属性进行查询,我们也无法确定用户是根据哪些属性进行查询。
- 以上的业务场景,都不能使用现有的技术来解决,或者说如果使用现有技术会十分麻烦。而动态SQL能够很好的解决该问题。
- 所谓动态SQL,简单来说就是指SQL语句是动态变化的。能够根据不同的业务场景,得到合适的SQL语句。
if标签
使用场景:多条件查询
<select id="selectByMulti" resultType="car"> <!--test属性为真则执行标签内的语句--> select * from t_car where 1 = 1 <!--疑问: 还有为什么核心配置文件中的mappers标签内不用指定Mapper.xml的路径了 需要再去看一下别名 --> <if test="#{brand} != null and #{brand} != ''"> and brand like "%"#{brand}"%" </if> <if test="#{price} != null and #{price} != ''"> and guide_price >= #{price} </if> <if test="#{carType} != null and #{carType} != ''"> and car_type = #{carType} </if> </select>
*1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
##### where标签
* 场景需求:在上面的if条件中,为了避免某些条件不成立导致sql语句格式的错误,我们在语句中添加了where 1 = 1这一段代码,这非常的不美观。
* 我们可以使用where标签使SQL语句更加智能化。
* 作用
* 当条件都不成立时,使用where标签后,不会生成where语句。
* 能够智能化的删减前面的and或or。比如:当第一个条件成立时,使用了where标签,那么它能够自动化的检测出and关键字是多余的,并且会将其删除。
* 这里需要注意的是:where标签只能检测出是否多余了and或or关键字并将多余的删除,并不能检测出是否缺失了and或or关键字,自然不会填补上缺失的关键字。还有,where标签只能检测and在前面的语句,对and在后面的语句无效。比如guide_price >= #{price} and.
* **所以建议在使用where标签使SQL语句更加智能化时,在每个条件中都写上and关键字,且写在前面**
* ```xml
<select id="selectByMultiWithWhere" resultType="car">
select * from t_car
<where>
<if test="#{brand} != null and #{brand} != ''">
and brand like "%"#{brand}"%"
</if>
<if test="#{price} != null and #{price} != ''">
and guide_price >= #{price}
</if>
<if test="#{carType} != null and #{carType} != ''">
and car_type = #{carType}
</if>
</where>
</select>
trim标签
trim标签也能解决以上问题
在trim标签中有4个属性
- prefix:在标签体前加上一个前缀
- suffix:在标签体后加上一个后缀
- prefixoverride:删除sql语句的前缀
- suffixoverride:删除sql语句的后缀,对where标签不能删除and出现在语句后面的情况做出了补充。比where标签功能更加强大
<select id="selectByMultiWithTrim" resultType="car"> select * from t_car <trim prefix="where" prefixOverrides="and|or"> <if test="#{brand} != null and #{brand} != ''"> and brand like "%"#{brand}"%" </if> <if test="#{price} != null and #{price} != ''"> and guide_price >= #{price} </if> <if test="#{carType} != null and #{carType} != ''"> and car_type = #{carType} </if> </trim> </select>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
##### set标签
* 需求场景:我们在进行数据库表的更新时,有可能只需要修改某一个字段,对于其他字段我们提交的数据都是null。如果采用原始做法,那么会将其他数据都更新为null,这肯定不是我们想要看到的。
* set标签能够解决以上问题,如果提交的数据为null,那么使用set标签将不会修改该字段。并且使用set标签还能够去除多余的逗号。
* ```xml
update t_car
<set>
<if test="carNum != null and carNum != ''">
car_num = #{carNum},
</if>
<if test="brand != null and brand != ''">
brand = #{brand},
</if>
<if test="guidePrice != null and guidePrice != ''">
guide_price = #{guidePrice},
</if>
<if test="produceTime != null and produceTime != ''">
produce_time = #{produceTime},
</if>
<if test="carType != null and carType != ''">
car_type = #{carType},
</if>
</set>
where id = #{id}
choose-when-otherwise标签
就是java中的嵌套条件语句:if-else if-else
select * from t_car <where> <choose> <when test="brand != null and brand != ''"> brand = #{brand} </when> <when test="price != null and price != ''"> guide_price >= #{price} </when> <otherwise> car_type = #{carType} </otherwise> </choose> </where>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
##### foreach标签
* 就是循环
* 批量删除
* ```xml
<delete id="deleteByIds">
delete from t_car where id in
<!--
collection:需要进行遍历的集合或数组对象 item:当前枚举的元素
separator:元素与元素之间以什么分隔
open:循环体以什么开始
close:循环体以什么结束
-->
<foreach collection="ids" item="a" separator="," open="(" close=")">
#{a}
</foreach>
<!--
另一种批量删除的方法
delete from t_car where
<foreach collection = "ids" item = "a" sparator="or">
id = #{a}
</foreach>
-->
</delete>
Sql与include标签
sql标签:将某个代码片段声明为sql语句
include标签:使用sql片段
可以提高代码复用性,使代码更容易维护
<sql id="carColumeSql"> id,car_num as carNum,brand,guide_price as guidePrice, produce_time as produceTime,car_type as carType </sql> <select id="selectById" resultType="com.deng.mybatis.pojo.Car"> select <include refid="carColumeSql"></include> from t_car where id = #{id}; </select>
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 dch'blog!