MyBatis 提供了动态 SQL 功能,允许在 SQL 查询中根据条件动态构建不同的 SQL 语句。使用动态 SQL 可以根据不同的条件拼接 SQL 语句,从而提升代码的灵活性和可维护性。MyBatis 中的动态 SQL 主要通过 XML
映射文件中的动态标签来实现。
常用的动态 SQL 标签
<if>
用于根据条件判断是否生成 SQL 片段。
<select id="selectUser" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">AND name = #{name}</if>
<if test="age != null">AND age = #{age}</if>
</where>
</select>
该查询会根据 name
和 age
是否为空来动态拼接 SQL 语句。
<choose>
、<when>
、<otherwise>
类似于 Java 中的 if-else
语句,用于根据多个条件选择执行不同的 SQL 语句。
<select id="selectUser" resultType="User">
SELECT * FROM users
<where>
<choose>
<when test="status == 'active'">AND active = 1</when>
<when test="status == 'inactive'">AND active = 0</when>
<otherwise>AND active IS NULL</otherwise>
</choose>
</where>
</select>
这段 SQL 会根据 status
值选择不同的 SQL 片段。
<foreach>
用于循环处理集合类型的参数,例如数组、List 等,生成批量 SQL 语句。
<select id="selectUsersByIds" resultType="User">
SELECT * FROM users
<where>
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</where>
</select>
如果 ids
是一个列表,<foreach>
会将每个 id
包装在 ()
中,并用逗号分隔。
<set>
用于动态生成 UPDATE
语句的 SET
部分。在 SQL 中,SET
后的字段更新会根据条件拼接。
<update id="updateUser">
UPDATE users
<set>
<if test="name != null">name = #{name},</if>
<if test="age != null">age = #{age},</if>
</set>
WHERE id = #{id}
</update>
通过 <set>
标签,可以动态地添加要更新的字段。如果某个字段为空,<if>
会避免添加该字段。
<trim>
用于在动态 SQL 语句中移除不必要的前缀和后缀,例如 AND
或 OR
。
<select id="selectUser" resultType="User">
SELECT * FROM users
<where>
<trim prefix="AND" prefixOverrides="AND ">
<if test="name != null">name = #{name}</if>
<if test="age != null">age = #{age}</if>
</trim>
</where>
</select>
prefix="AND"
会在所有条件前加上 AND
,而 prefixOverrides="AND "
会去除首部的 AND
。
<bind>
用于在 SQL 中创建临时变量。它可以将参数值或表达式赋给一个临时变量,然后在 SQL 中引用该变量。
<select id="selectUser" resultType="User">
<bind name="prefix" value="'%' + name + '%'" />
SELECT * FROM users WHERE name LIKE #{prefix}
</select>
通过 <bind>
,可以创建一个 prefix
临时变量,并在 SQL 中使用。
示例:动态 SQL 查询用户
<select id="selectUsers" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">AND name = #{name}</if>
<if test="age != null">AND age = #{age}</if>
<if test="status != null">AND status = #{status}</if>
</where>
</select>
在这个例子中,<where>
标签自动为每个条件添加 AND
,如果没有条件,<where>
会去掉不必要的 AND
。
小结
MyBatis 提供的动态 SQL 使得 SQL 查询更加灵活,可以根据实际需求动态构建 SQL 语句。常用的动态 SQL 标签包括 <if>
、<choose>
、<foreach>
、<set>
和 <trim>
等,它们可以帮助开发者根据不同的业务需求生成不同的 SQL 查询。