MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。
动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。
一,使用sql片段
定义sql片段:
<!-- 定义sql片段 id:sql片段的唯一标识
经验:定义sql片段是基于单表定义,这样重用性比较高
sql片段中尽量不包含where
-->
<sql id="query_user_where">
<if test="userCustom != null">
<if test="userCustom.sex != null and userCustom.sex!=''">
and user.sex=#{userCustom.sex}
</if>
<if test="userCustom.username != null and userCustom.username!=''">
and user.username like '%${userCustom.username}%'
</if>
<if test="ids!=null">
<!-- 使用foreache遍历id
collection:指定输入对象中集合属性
item:每个遍历生成对象中
open:开始遍历时候要拼接的串
close:结束遍历需要拼接的串
separator:遍历的两个对象中间需要拼接的串
-->
<!-- 使用下面的sql拼接:
and (id=1 or id=10 or id=16)
-->
<!-- <foreach collection="ids" item="item_id" open="and (" close=")" separator="or">
每次遍历需要拼接的串
id=#{item_id}
</foreach> -->
<!-- 实现and id in(1,10,22) -->
<foreach collection="ids" item="item_id" open="and id in(" close=")" separator=",">
<!-- 每次遍历需要拼接的串 -->
#{item_id}
</foreach>
</if>
</if>
</sql>
引用sql片段:
<!-- 用户信息综合查询 #{userCustom.sex}:取出包装对象中性别的值 -->
<select id="findUserList" parameterType="UserQueryVo"
resultType="UserCustom">
select id,username,birthday,sex,address from user
<!-- where可以自动去掉条件中的第一个and -->
<where>
<!-- 引用sql片段的id,如果refid指定的id不在本mapper文件中,需要加上namespace -->
<include refid="query_user_where"></include>
<!-- 在这里还要引用其他sql片段 -->
</where>
</select>
其他标签:
- choose (when, otherwise)
- trim (where, set)
- foreach
- 。。
二,foreach标签的使用
<if test="ids!=null">
<!-- 使用foreache遍历id
collection:指定输入对象中集合属性
item:每个遍历生成对象中
open:开始遍历时候要拼接的串
close:结束遍历需要拼接的串
separator:遍历的两个对象中间需要拼接的串
-->
<!-- 使用下面的sql拼接:
and (id=1 or id=10 or id=16)
-->
<!-- <foreach collection="ids" item="item_id" open="and (" close=")" separator="or">
每次遍历需要拼接的串
id=#{item_id}
</foreach> -->
<!-- 实现and id in(1,10,22) -->
<foreach collection="ids" item="item_id" open="and id in(" close=")" separator=",">
<!-- 每次遍历需要拼接的串 -->
#{item_id}
</foreach>
</if>
定义的vo中加入list: