文章目录
- 1、if(and/or)
- 2、where
- 3、trim
- 4、set
- 5、choose、when、otherwise
- 6、foreach
- 7、sql
Mybatis框架的 动态SQL 技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决 拼接SQL语句字符串时的痛点问题。
1、if(and/or)
if标签可通过test属性的表达式进行判断,若表达式的结果为true,则标签中的内容会执行;反之标签中 的内容不会执行
<select id="getStudentByCondition" parameterType="Map" resultType="Student">
SELECT s_id id,s_name name,address,age FROM student WHERE 1=1
<if test="name!='' and name!=null">
AND name=#{name}
</if>
<if test="address!='' and address!=null">
AND address=#{address}
</if>
</select>
2、where
参考上例,where后面跟了个 1=1,是为了防止where 后面直接接and导致生成错误sql,用
<where>
标签完美解决where和 if一般结合使用,where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除(and/or)去掉
注意:where标签不能去掉条件最后多余的and或or
<select id="getStudentByCondition" parameterType="Map" resultType="Student">
SELECT s_id id,s_name name,address,age FROM student
<where>
<if test="name!='' and name!=null">
AND name=#{name}
</if>
<if test="address!='' and address!=null">
AND address=#{address}
</if>
</where>
</select>
3、trim
如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。
trim用于去掉或添加标签中的内容;常用属性如下:
prefix
:在trim标签中的内容的前面添加某些内容
prefixOverrides
:在trim标签中的内容的前面去掉某个内容或通过管道符分隔的文本序列
suffix
:在trim标签中的内容的后面添加某些内容
suffixOverrides
:在trim标签中的内容的后面去掉某个内容或通过管道符分隔的文本序列
<!--如果我们把连接符写在后面...-->
<select id="getStudentByCondition" parameterType="Map" resultType="Student">
SELECT s_id id,s_name name,address,age FROM student
<trim prefix="where" prefixOverrides="and|or">
<if test="name!='' and name!=null">
name=#{name} AND
</if>
<if test="address!='' and address!=null">
address=#{address} AND
</if>
</trim>
</select>
4、set
用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。
<update id="updateById" parameterType="hom.wang.mybatis.model.User">
update user
<set>
<if test="userName != null and userName != ''">
user_name=#{userName},
</if>
<if test="age != null and age != ''">
age=#{age},
</if>
<if test="sex != null and sex != ''">
sex=#{sex},
</if>
<if test="phone != null and phone != ''">
phone=#{phone},
</if>
<if test="email != null and email != ''">
email=#{email},
</if>
</set>
where user_id=#{userId}
</update>
set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。与 set 元素等价的自定义 trim 元素如下:
<trim prefix="SET" suffixOverrides=","> ... </trim>
注意,我们覆盖了后缀值设置,并且自定义了前缀值。
5、choose、when、otherwise
类似 if..else if...else
或 switch
语句
<select id="getStudentByCondition" parameterType="List" resultType="Student">
SELECT s_id id,s_name name,address,age FROM student
<where>
<choose>
<when test="name!=''">
s_name like #{name}
</when>
<when test="address!=''">
address like #{address}
</when>
<otherwise>
1=0
</otherwise>
</choose>
</where>
</select>
6、foreach
动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。
属性:
collection:设置要循环的数组或集合(建议使用
@Param
指定)
index:当前迭代的序号
item:本次迭代获取到的元素
open:开始
close:结束
separator:分隔符
<!--int deleteByArray(Integer[] ids)
如果不用@Param指定参数名,数组的话默认参数map是[arry, arg0],集合就是[collection, list, arg0]
-->
<delete id="deleteByArray">
delete from goods where
<foreach collection="array" item="id" open=" id in (" close=")" separator=",">
#{id}
</foreach>
</delete>
<!--批量添加
int insertSome(List<User> users)
-->
<insert id="insertSome">
insert into user values
<foreach collection="list" item="user" separator=",">
(null, #{user.userName}, #{user.age}, #{user.sex}, #{user.phone}, #{user.email})
</foreach>
</insert>
7、sql
sql片段,可以记录一段公共sql片段,在使用的地方通过include标签进行引入。
<sql id="BaseSql">
user_id, user_name, age, sex, phone, email
</sql>
<select id="selectAll" resultMap="BaseResultMap">
select <include refid="BaseSql"/>
from user
</select>