MyBatis 中的动态 SQL 是一种允许在 SQL 语句中根据不同的条件动态生成 SQL 语句的技术。它可以根据不同的条件生成不同的 SQL 语句,从而达到灵活构建 SQL 语句的目的。动态 SQL 可以减少代码的重复度,提高代码的可维护性和可读性。
动态 SQL 使用 OGNL(Object-Graph Navigation Language)表达式来判断条件,根据条件来决定是否包含某个 SQL 片段。OGNL 表达式是一种基于 Java 表达式的语言,可以访问 Java 对象和方法,用于动态生成 SQL 语句的条件判断。
动态 SQL 在 MyBatis 中主要有以下几种方式:
if 标签
if 标签用于判断一个条件是否成立,如果成立,则包含 if 标签内的 SQL 语句。如果不成立,则忽略 if 标签内的 SQL 语句。
示例代码:
<select id="getUserList" parameterType="User" resultType="User">
SELECT * FROMusers
WHERE 1=1
<if test="id != null">
AND id = #{id}
</if>
<if test="username != null">
AND username = #{username}
</if>
<if test="email != null">
AND email = #{email}
</if>
</select>
在上面的示例代码中,如果传入的 User 对象中 id、username、email 中有值,则会将对应的 SQL 语句包含进去,否则忽略。
choose、when、otherwise 标签
choose 标签类似于 Java 中的 switch 语句,用于根据不同的情况生成不同的 SQL 语句。
示例代码:
<select id="getUserList" parameterType="User" resultType="User">
SELECT * FROM users
WHERE 1=1
<choose>
<when test="id != null">
AND id = #{id}
</when>
<when test="username != null">
AND username = #{username}
</when>
<when test="email != null">
AND email = #{email}
</when>
<otherwise>
AND 1=2
</otherwise>
</choose>
</select>
在上面的示例代码中,如果传入的 User 对象中 id、username、email 中有值,会将对应的 SQL 语句包含进去。如果没有传入任何值,则会将 otherwise 标签内的 SQL 语句包含进去。
where 标签
where 标签可以在 SQL 语句中动态生成 WHERE 子句,避免在 SQL 语句中重复写 WHERE 子句。
示例代码:
<select id="getUserList" parameterType="User" resultType="User">
SELECT * FROM users
<where>
<if test="id != null">
AND id = #{id}
</if>
<if test="username != null">
AND username = #{username}
</if>
<if test="email != null">
AND email = #{email}
</if>
</where>
</select>
在上面的示例代码中,如果传入的 User 对象中 id、username、email 中有值,会将对应的 SQL 语句包含进去,并在 SQL 语句中生成 WHERE 子句。
set 标签
set 标签可以在 SQL 语句中动态生成 SET 子句,避免在SQL 语句中重复写 SET 子句。
示例代码:
<update id="updateUser" parameterType="User">
UPDATE users
<set>
<if test="username != null">
username = #{username},
</if>
<if test="password != null">
password = #{password},
</if>
<if test="email != null">
email = #{email},
</if>
</set>
WHERE id = #{id}
</update>
在上面的示例代码中,如果传入的 User 对象中 username、password、email 中有值,会将对应的 SQL 语句包含进去,并在 SQL 语句中生成 SET 子句。
foreach 标签
foreach 标签用于遍历一个集合,并将集合中的元素作为参数传递给 SQL 语句中的属性。
示例代码:
<select id="getUserListByIds" parameterType="List" resultType="User">
SELECT * FROM users
WHERE id IN
<foreach item="id" collection="list" open="(" separator="," close=")">
#{id}
</foreach>
</select>
在上面的示例代码中,将传入的 List 对象中的元素作为参数传递给 SQL 语句中的 id 属性,并使用 IN 关键字查询对应的用户信息。
总的来说,动态 SQL 可以根据不同的条件动态生成 SQL 语句,从而实现灵活构建 SQL 语句的功能。在 MyBatis 中,动态 SQL 主要使用 if、choose、when、otherwise、where、set、foreach 等标签来实现。下面给出一个完整的示例代码,展示如何使用动态 SQL 实现灵活的 SQL 语句构建。
示例代码:
<select id="getUserList" parameterType="User" resultType="User">
SELECT * FROM users
<where>
<if test="id != null">
AND id = #{id}
</if>
<if test="username != null and username != ''">
AND username = #{username}
</if>
<if test="email != null and email != ''">
AND email = #{email}
</if>
</where>
<choose>
<when test="order != null and order == 'id'">
ORDER BY id
</when>
<when test="order != null and order == 'username'">
ORDER BY username
</when >
<when test="order != null and order == 'email'">
ORDER BY email
</when>
<otherwise>
ORDER BY id
</otherwise>
</choose>
LIMIT #{offset}, #{limit}
</select>
<update id="updateUser" parameterType="User">
UPDATE users
<set>
<if test="username != null and username != ''">
username = #{username},
</if>
<if test="password != null and password != ''">
password = #{password},
</if>
<if test="email != null and email != ''">
email = #{email},
</if>
</set>
WHERE id = #{id}
</update>
<select id="getUserListByIds" parameterType="List" resultType="User">
SELECT * FROM users
WHERE id IN
<foreach item="id" collection="list" open="(" separator="," close=")">
#{id}
</foreach>
</select>
在上面的示例代码中,getUserList 方法根据传入的 User 对象中的 id、username、email 属性动态生成 SQL 语句,并根据传入的 order 参数决定排序方式。updateUser 方法根据传入的 User 对象中的属性动态生成 SQL 语句。getUserListByIds方法根据传入的 List 对象中的元素动态生成 SQL 语句,查询对应的用户信息。
小结
总的来说,动态 SQL 是 MyBatis 中非常重要的功能之一,可以让我们更灵活地构建 SQL 语句,提高代码的可维护性和可读性。