动态 SQL 指的是在运行时根据条件动态拼接 SQL 语句,而不是在代码中写死 SQL。它常见于 MyBatis、JDBC + 字符串拼接、Spring JDBC 等场景。下面以 MyBatis 为主进行说明(最常用),并补充其他实现方式。
实际业务中 SQL 条件往往不确定,例如:
where name = ? and age = ?MyBatis 提供了 XML 标签 来实现动态 SQL。
<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>
✅ <where> 会自动去掉多余的 AND / OR
<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<Integer> ids = Arrays.asList(1,2,3);
生成 SQL:
SELECT * FROM user WHERE id IN (1,2,3)
<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>
@Select("<script>" +
"SELECT * FROM user" +
"<where>" +
" <if test='name != null'>AND name = #{name}</if>" +
"</where>" +
"</script>")
List<User> selectUser(@Param("name") String name);
String sql = "SELECT * FROM user WHERE 1=1";
if (name != null) {
sql += " AND name = '" + name + "'";
}
❌ SQL 注入风险 ✅ 实际项目中不建议使用
StringBuilder sql = new StringBuilder("SELECT * FROM user WHERE 1=1");
List<Object> params = new ArrayList<>();
if (name != null) {
sql.append(" AND name = ?");
params.add(name);
}
#{}(预编译)${}(字符串替换)if 过多导致 SQL 复杂| 方式 | 推荐度 | 说明 |
|---|---|---|
| MyBatis XML | ⭐⭐⭐⭐⭐ | 最常用、最安全 |
| MyBatis 注解 | ⭐⭐⭐ | 简单 SQL |
| JDBC 拼接 | ❌ | 不安全 |
| Spring JDBC | ⭐⭐⭐ | 中等复杂度 |
如果你愿意,我可以:
你更想了解哪一种?
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。