MyBatis学习总结[5]-动态 SQL
推荐去看官方文档,写的很清楚。
本文是对官方文档的摘录和个人理解,给自己做的笔记
动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。
- if
- choose (when, otherwise)
- trim ,where, set
- foreach
if标签
动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分。
<select id="getCars" resultMap="carConstructor" >
select
c.id as id,
c.name as name,
c.money as money,
c.age as age,
c.u_id as uId
from car c
where
<!-- 这里有个问题如果第一个if为false,则where会被拼接成
where and c.id=××,因为if语句不会自动判断是否多前缀 -->
<if test="name!=null and name!=''">
c.name=#{name}
</if>
<if test="id!=null and id!=''">
and c.id=#{id}
</if>
<if test="age!=null and age!=''">
and c.age=#{age}
</if>
</select>
trim标签
自定义 trim 元素和 where,set 元素等价,在where,set元素不能正常工作的时候用。
<select id="getCars" resultMap="carConstructor" >
select
c.id as id,
c.name as name,
c.money as money,
c.age as age,
c.u_id as uId
from car c
<!-- prefix指定要添加的前缀;suffix指定要添加的后缀;prefixOverrides指定要去掉的前缀,包括空格;suffixOverrides指定要去掉的后缀 -->
<trim prefix="where" prefixOverrides="and ">
<if test="name!=null and name!=''">
and c.name=#{name}
</if>
<if test="id!=null and id!=''">
and c.id=#{id}
</if>
<if test="age!=null and age!=''">
and c.age=#{age}
</if>
</trim>
</select>
where标签
where 元素知道只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且,若最后的内容是“AND”或“OR”开头的,where 元素也知道如何将他们去除。
<select id="getCars" resultMap="carConstructor" >
select
c.id as id,
c.name as name,
c.money as money,
c.age as age,
c.u_id as uId
from car c
<where>
<if test="name!=null and name!=''">
and c.name=#{name}
</if>
<if test="id!=null and id!=''">
and c.id=#{id}
</if>
<if test="age!=null and age!=''">
and c.age=#{age}
</if>
</where>
</select>
set标签
set 元素可以被用于动态包含需要更新的列,而舍去其他的。set 元素会动态前置 SET 关键字,同时也会消除无关的逗号,因为用了条件语句之后很可能就会在生成的赋值语句的后面留下这些逗号。
<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio},</if>
</set>
where id=#{id}
</update>
foreach标签
你可以将任何可迭代对象(如列表、集合等)和任何的字典或者数组对象传递给foreach作为集合参数。当使用可迭代对象或者数组时,index是当前迭代的次数,item的值是本次迭代获取的元素。当使用字典(或者Map.Entry对象的集合)时,index是键,item是值。
<!-- open指定开始字符,close知道关闭字符,separator指定分割符 -->
<foreach item="item" index="index" collection="companyIds" open="(" separator="," close=")" >
#{item}
</foreach>
choose标签
它有点像 Java 中的 switch 语句
<select id="getCars" resultMap="carConstructor" >
select
c.id as id,
c.name as name,
c.money as money,
c.age as age,
c.u_id as uId
from car c
where
<choose>
<!-- 相当于case -->
<when test="name!=null and name!=''">
and c.name=#{name}
</when>
<when test="id!=null and id!=1">
and c.id=#{id}
</when>
<!-- 相当于default -->
<otherwise>
and 1=1
</otherwise>
</choose>
</select>