目录
MyBatis 是一款优秀的持久层框架,它的强大之处正是 SQL 语句映射,这一章介绍常用的动态 SQL。
详细配置参阅《MyBatis介绍与配置》
增删改查参阅《MyBatis实践之增删改查》
一、 概述
动态 SQL 是 MyBatis 的强大特性之一,通过不同参数生成不同的 SQL,可以动态地对数据持久层进行操作,而不需要每个数据访问操作都要进行手动地拼接 SQL 语句。
二、动态语句
1. if
<if>
语句可以根据条件指定 SQL 部分,例如 where
条件。
查询数据接口如下:
public interface UserSqlMapper {
List<User> selectByUsername(@Param("username") String username, @Param("status") Integer status);
}
对应映射语句如下:
<select id="selectByUsername" resultType="User">
SELECT * FROM t_user WHERE 1 = 1
<if test="status != null">
AND status = #{status}
</if>
<if test="username != null and username != ''">
AND username = #{username}
</if>
</select>
上面语句当 status
不为 null
时,以及 username
不为空字符串时,对应的查询条件才会生效。
2. choose、when、otherwise
<choose>
语句类似于 Java 的 switch
语句,可以从多个条件中选择一个使用。
<select id="selectByUsername" resultType="User">
SELECT * FROM t_user WHERE 1 = 1
<choose>
<when test="status != null">
AND status = #{status}
</when>
<otherwise>
AND username = #{username}
</otherwise>
</choose>
</select>
上面语句根据 status
是否为 null
而执行不同的查询条件,每次查询只存在一个查询条件。
3. trim、where、set
在前面的例子中,where
后面都会加上 1=1
这个条件,为了解决当所有条件都没生效时,where
条件为空而产生异常的问题。
在更新语句 set
后面也会出现同样的问题,可以使用 <trim>
语句通过指定前缀和后缀的方式来解决。
MyBatis 也提供更简单的 <where>
语句和 <set>
语句来解决这个问题。
例如下面两个接口:
public interface UserSqlMapper {
List<User> selectByUsername(@Param("username") String username, @Param("status") Integer status);
void updateById(User user);
}
对应的 <trim>
映射 where
语句如下:
<select id="selectByUsername" resultType="User">
SELECT * FROM t_user
<trim prefix="WHERE" prefixOverrides="AND|OR">
<if test="status != null">
AND status = #{status}
</if>
<if test="username != null and username != ''">
AND username = #{username}
</if>
</trim>
</select>
对应的 <where>
映射语句如下:
<select id="selectByUsername" resultType="User">
SELECT * FROM t_user
<where>
<if test="status != null">
AND status = #{status}
</if>
<if test="username != null and username != ''">
AND username = #{username}
</if>
</where>
</select>
对应的 <trim>
映射 update
语句如下:
<update id="updateById">
UPDATE t_user
<trim prefix="SET" suffixOverrides=",">
<if test="status != null">
status = #{status},
</if>
<if test="username != null and username != ''">
username = #{username},
</if>
</trim>
</update>
对应的 <set>
映射语句如下:
<update id="updateById">
UPDATE t_user
<set>
<if test="status != null">
status = #{status},
</if>
<if test="username != null and username != ''">
username = #{username},
</if>
</set>
</update>
4. foreach
<foreach>
可以对集合进行遍历,例如使用 IN
条件语句的时候。
查询数据接口如下:
public interface UserSqlMapper {
List<User> selectInIdList(@Param("idList") List<Long> idList);
}
对应映射语句如下:
<select id="selectInIdList" resultType="User">
SELECT * FROM t_user
<where>
<foreach item="item" index="index" collection="idList" open="id IN (" separator="," close=")" nullable="true">
#{item}
</foreach>
</where>
</select>
item
指定元素,index
指定索引。
5. script
<script>
可以在接口上的注解中使用动态SQL。
例如查询数据接口如下:
public interface UserSqlMapper {
@Select("<script>" +
"SELECT * FROM t_user" +
"<where>" +
" <if test='status != null'>AND status = #{status}</if>" +
" <if test='username != null'>AND username = #{username}</if>" +
"</where>" +
"</script>")
List<User> selectByUser(User user);
}
<script>
标签里面的内容和在 XML 文件中的动态 SQL 语法一致。
三、附录
1. 示例代码
Gitee 仓库:https://gitee.com/code_artist/mybatis
2. 参考文献
MyBatis 3 官方文档:https://mybatis.org/mybatis-3/zh/
标签:语句,username,status,user,SQL,MyBatis,动态 From: https://www.cnblogs.com/code-artist/p/mybatis-4.html