想了解MyBatis框架的动态sql吗?走起!
背景
前两天在做项目的过程中接触到了MyBatis的动态sql,觉得这是MyBatis中比较实用但是也是比较复杂的一个点,所以,特意拿出来单独做一个笔记,以免自己忘记。
生成动态sql的基本原理
MyBatis生成动态sql的话主要是借助于各种各样的标记,就像我们在程序中使用的关键字一样,这是一种约定好的东西。
常用的标记列举如下:
1. if、choose标记
2. where、set、trim标记
3. foreach标记
动态sql的实际使用
- if标记
场景:
当money字段传入的时候,就按照money字段查,否则查找出库里所有的字段。
例子:
select * from tableName
where 1=1
<if test="money!=null">
and money>#{money}
</if>
- choose标记
场景:当传入的对象有多个参数需要判断的时候,我们就必须要使用choose标记,比如说判断完用户名判断id,最后判断密码等操作。
特点:顺序执行。
疑问:每一个都必须执行,otherwise标记的作用是最终拦截吗?
例子:
<!--test就是对条件的判断结果,也就是这个被if进行最终的判断-->
<choose>
<when test="userName!=null">
and userName like#{userName}
</when>
<when test="id!=null">
and id=#{id}
</when>
<otherwise>
and password is not null
</otherwise>
</choose>
- where标记
场景:智能化的添加或者削减and运算符
例子:改写我们上面的sql,不需要where 1=1这样一句了
如果第一个if不成立,会智能的去掉第二个if的关键字
<where>
<if test="userName!=null">
userName like #{userName}
</if>
<if test="id!=null">
and id=#{id}
</if>
</where>
- set标记
场景:和where标记类似,会去掉updata操作中多余的逗号,如果没有这个标记,生成的sql就会报错。
例子:如果第二个if不成立,就会多出来一个逗号,sql会报错。
<set>
<if test=“userName!=null”>userName=#{userName},</if>
<if test=“password!=null”>password=#{password},</if>
</set>
- trim标记-格式化标记
场景:可以与其他标记组合完成where和set标记的功能
trim标记有四个很重要的属性列举如下:
属性名 | 作用 |
---|---|
prefix | 前缀增加 |
suffix | 后缀增加 |
prefixOverrides | 自动判断前置 |
suffixOverrides | 自动判断后置 |
例子:
1.使用trim标记实现set标记的作用。
<trim prefix="Set" suffix="WHERE id =#{id}" suffixOverrides=",">
<if test="userName!=null">
userName=#{userName}
</if>
</trim>
2.代替where标记
select * from tableName
<trim prefix="WHERE" prefixOverrides="and|or">
<if test="userName!=null">
userName like #{userName}
</if>
<if test="id!=null">
and id=#{id}
</if>
</trim>
- foreach标记-在项目中用的最多了
场景:
循环查询
循环写入更新
当然,foreach标记的属性如下:
属性名 | 作用及用法 |
---|---|
item | 每一次的迭代结果 |
collection | 循环集合或指定类型 |
separator | 元素之间的分隔符,可选 |
open | 开始符号,可选 |
close | 结束符号,可选 |
index | list或者数组的序号,可选 |
例子:1.in查询
select * from tableName
<where>
id in
<foreach item="item" index="index" collection="List" open="(" separator="," close=")">
#{item}
</foreach>
</where>
2.一次插入多条数据
insert into tableName(userName,password) values
<foreach item="item" index="key" collection="list" open="" separator="," close="">
(#{item.userName},#{item.password})
</foreach>
总结
曾经我们需要写在代码里的东西,现在我们可以利用动态sql的标签将其简化,这也将大大提升我们的代码的可维护性,这是我们最大的收获。
当然,我们在掌握一个新的功能之后一定要非常明确,支持新功能的版本都有哪些?这是非常重要的。