MyBatis 提供使用 ognl 表达式动态生成 SQL的功能。
1. if
2. where
where 可以自动处理掉第一个拼接条件里的 and
<!-- 动态 sql 查询用户信息 -->
<select id="findUserByDynamicSql" parameterType="user" resultType="user">
select * from users
<!-- where 可以自动处理第一个 and -->
<where>
<!-- 注意:要做不为null 和 '' 校验 -->
<if test="userId != null and userId != ''">
and users.userId = #{userId}
</if>
<if test="username != null and username != ''">
and users.username like '%${username}%'
</if>
</where>
</select>
3. foreach
foreach 可以向 SQL 传递数组、List<E> 等,下面介绍一个数组的例子
<!-- 动态 sql 查询用户信息 -->
<select id="findUserByDynamicSql" parameterType="user" resultType="user">
select * from users
<!-- where 可以自动处理第一个 and -->
<where>
<!-- 解析传递过来的多个 userId -->
<!-- ids 是结合;item 是集合中的项目变量 -->
<foreach collection="ids" item="id" open="userId in(" close=")" separator=",">
#{id}
</foreach>
<!-- 注意:要做不为null 和 '' 校验 -->
<if test="userId != null and userId != ''">
and users.userId = #{userId}
</if>
<if test="username != null and username != ''">
and users.username like '%${username}%'
</if>
</where>
</select>
运行结果:
如果上面传递的数组中是 pojo 对象,那么collection 属性名称必须是 array(如果是传递 List 对象,
那么collection属性名称是 list),而传递到 sql 当中的参数则是
pojo.属性名。如下:
index:为数组的下标, item:数组中每个元素的名称,随便定义
open:循环开始, close:循环结束 separator:中间分隔输出
<select id="selectUserByArray" parameterType="Object[]" resultType="user">
select * from user
<where>
<!-- 传递数组 -->
<if test="array!=null">
<foreach collection="array" index="index" item="item"
open="and id in(" separator="," close=")" >
#{item.id}
</foreach>
</if>
</where>
</select>
4. SQL 片段
按照上面的 动态SQL 写法,可能会产生很多重复的 sql。为了重用这些 sql 减少代码,可以将重复的 sql
提取出来,使用时通过 include 引用。
a. 定义 SQL 片段,将 重复的 sql 抽取出来
<!-- 定义SQL 片段 -->
<sql id="query_user_ByUserName">
<if test="username != null and username != ''">
and users.username like '%${username}%'
</if>
</sql>
<sql id="query_user_ByUserId">
<!-- 注意:要做不为null 和 '' 校验 -->
<if test="userId != null and userId != ''">
and users.userId = #{userId}
</if>
</sql>
<sql id="query_user_ByIdArray">
<!-- 解析传递过来的多个 userId -->
<!-- ids 是结合;item 是集合中的项目变量 -->
<foreach collection="ids" item="id" open="userId in(" close=")" separator=",">
#{id}
</foreach>
</sql>
b. 在 SQL 中引用 sql 片段,可以对比上面所举得例子中的代码
<!-- 动态 sql 查询用户信息 -->
<select id="findUserByDynamicSql" parameterType="user" resultType="user">
select * from users
<!-- where 可以自动处理第一个 and -->
<where>
<include refid="query_user_ByIdArray"></include>
<include refid="query_user_ByUserId"></include>
<include refid="query_user_ByUserName"></include>
</where>
</select>