在 MyBatis 中,“动态写 SQL”通常指 根据条件动态拼接 SQL,MyBatis 提供了多种机制来实现,下面按常见程度和使用场景给你系统讲一下。
<if> 条件拼接<select id="selectUser" resultType="User">
SELECT * FROM user
WHERE 1=1
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</select>
✅ 条件满足才拼接 SQL
<where> 自动处理 AND / OR避免手写 1=1
<select id="selectUser" resultType="User">
SELECT * FROM user
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
✅ 自动去掉多余 AND
<choose> / <when> / <otherwise>(类似 switch)<select id="selectUser" resultType="User">
SELECT * FROM user
<where>
<choose>
<when test="type == 'A'">
AND type = 'A'
</when>
<when test="type == 'B'">
AND type = 'B'
</when>
<otherwise>
AND status = 1
</otherwise>
</choose>
</where>
</select>
<foreach> 循环(IN 查询)<select id="selectByIds" resultType="User">
SELECT * FROM user
WHERE id IN
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
调用:
List<User> selectByIds(@Param("ids") List<Integer> ids);
<set> 动态更新<update id="updateUser">
UPDATE user
<set>
<if test="name != null">name = #{name},</if>
<if test="age != null">age = #{age},</if>
</set>
WHERE id = #{id}
</update>
✅ 自动去掉多余逗号
<trim> 更灵活的控制<trim prefix="WHERE" prefixOverrides="AND | OR">
<if test="name != null">
AND name = #{name}
</if>
</trim>
适合 SQL 变化非常复杂 的场景
@SelectProvider(type = UserSqlProvider.class, method = "listUser")
List<User> listUser(User user);
public class UserSqlProvider {
public String listUser(User user) {
return new SQL(){{
SELECT("*");
FROM("user");
if (user.getName() != null) {
WHERE("name = '" + user.getName() + "'");
}
}}.toString();
}
}
⚠️ 注意 SQL 注入风险,推荐用条件拼 SQL + 参数
如果你用的是 MyBatis-Plus,动态 SQL 非常简单:
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like(name != null, "name", name);
wrapper.eq(age != null, "age", age);
✅ 自动防注入
✅ 代码级动态 SQL
<sql> + <include><sql id="userColumns">
id, name, age
</sql>
<select id="selectUser">
SELECT <include refid="userColumns"/>
FROM user
</select>
| 场景 | 推荐方式 |
|---|---|
| 普通条件查询 | XML 动态 SQL |
| 多表复杂 SQL | XML + <foreach> |
| SQL 极端动态 | Provider |
| 快速开发 | MyBatis-Plus |
| 公共 SQL 片段 | <sql> |
如果你愿意,可以告诉我:
我可以直接帮你写一份可运行的示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。