MyBatis的一个强大的特性之一通常是它的动态SQL能力。提供了OGNL表达式动态生成SQL的功能。动态SQL有:
- if
- choose,when,otherwise
- where,set
- foreach
if
场景:查询男性用户,如果输入了姓名,则按姓名查询
List<User> queryUserList(@Param("name") String name);
<select id="queryUserList" resultType="com.example.test.model.User">
select * from tb_user WHERE sex=1
<if test="name!=null and name.trim()!=''">
and name like '%${name}%'
</if>
</select>
choose..when..otherwise
场景:查询男性用户,当输入了姓名则按照姓名模糊查找,当输入了年龄则按照年龄查找,否则查找姓名为“xiaoyu”的用户。
List<User> queryUserListByNameOrAge(@Param("name") String name,@Param("age") Integer age);
<select id="queryUserListByNameOrAge" resultType="com.example.test.model.User">
select * from tb_user WHERE sex=1
<!--
1. 一旦有条件成立的when,后续的when则不会执行
2. 当所有的when都不执行时,才会执行otherwise
-->
<choose>
<when test="name!=null and name.trim()!=''">
and name like '%${name}%'
</when>
<when test="age!=null">
and age = #{age}
</when>
<otherwise>
and name='xiaoyu'
</otherwise>
</choose>
</select>
where
场景:查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询,如果两者都输入,两个条件都要成立。
List<User> queryUserListByNameAndAge(@Param("name") String name,@Param("age") Integer age);
<select id="queryUserListByNameAndAge" resultType="com.example.test.model.User">
select * from tb_user
<!--如果多出一个and,会自动去除,如果缺少and或者多出多个and则会报错-->
<where>
<if test="name!=null and name.trim()!=''">
and name like '%${name}%'
</if>
<if test="age!=null">
and age = #{age}
</if>
</where>
</select>
set
场景:修改用户信息,输入什么字段就改什么字段
public void updateUser(User user);
<update id="updateUser" parameterType="com.example.test.model.User">
UPDATE tb_user
<set>
<if test="userName!=null">user_name = #{userName},</if>
<if test="password!=null">password = #{password},</if>
<if test="name!=null">name = #{name},</if>
<if test="age!=null">age = #{age},</if>
<if test="sex!=null">sex = #{sex},</if>
<if test="birthday!=null">birthday = #{birthday},</if>
updated = now(),
</set>
WHERE
(id = #{id});
</update>
foreach
场景:按照多个id查询用户信息。
List<User> queryUserListByIds(@Param("ids") Long[] ids);
<select id="queryUserListByIds" resultType="com.example.test.model.User">
select * from tb_user where id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
trim
如果 where 元素没有按正常套路出牌,我们还是可以通过自定义 trim 元素来定制我们想要的功能。比如,和 where 元素等价的自定义 trim 元素为:
<trim prefix="WHERE" prefixOverrides="AND | OR">
...
</trim>
trim 也可用于比如set的操作:
<trim prefix="SET" suffixOverrides=",">
...
</trim>
举例:
<update id="updateUser" parameterType="com.example.test.model.User">
UPDATE tb_user
<trim prefix="set" suffixOverrides=",">
<if test="userName!=null">user_name = #{userName},</if>
<if test="password!=null">password = #{password},</if>
<if test="name!=null">name = #{name},</if>
<if test="age!=null">age = #{age},</if>
<if test="sex!=null">sex = #{sex},</if>
<if test="birthday!=null">birthday = #{birthday},</if>
updated = now(),
</trim>
WHERE
(id = #{id});
</update>
bind
bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>