温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Dynamic SQL 动态SQL怎么用

发布时间:2026-07-14 08:15:13 来源:亿速云 阅读:85 作者:小樊 栏目:数据库

动态 SQL(Dynamic SQL) 通常指 在运行时才确定最终要执行的 SQL 语句,而不是在写代码时就写死。它常见于 MyBatis、JDBC、存储过程、ORM 框架 中。下面我按 使用场景 + 示例 给你讲清楚。


一、什么是动态 SQL?

静态 SQL:SQL 在编译期就固定了

SELECT * FROM user WHERE id = 1;

动态 SQL:SQL 根据条件、参数、状态在运行时拼接

SELECT * FROM user WHERE 1=1
<if test="name != null">
  AND name = #{name}
</if>

二、MyBatis 中的动态 SQL(最常见 ✅)

1️⃣ <if> 条件判断

<select id="findUser" 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>

✅ 如果 name 为空,就不会拼 AND name = ?


2️⃣ <choose> / <when> / <otherwise>(类似 switch)

<select id="findUser" resultType="User">
  SELECT * FROM user
  WHERE 1=1
  <choose>
    <when test="type == 'A'">
      AND type = 'A'
    </when>
    <when test="type == 'B'">
      AND type = 'B'
    </when>
    <otherwise>
      AND type = 'C'
    </otherwise>
  </choose>
</select>

3️⃣ <where> 自动处理 AND / OR

<select id="findUser" 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
✅ 如果条件为空,不会生成 WHERE


4️⃣ <set> 用于 UPDATE

<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>

✅ 自动去掉末尾多余的 ,


5️⃣ <foreach> 遍历集合(IN 查询)

<select id="findByIds" 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)

三、JDBC 中的动态 SQL(不推荐但常见)

String sql = "SELECT * FROM user WHERE 1=1";
if (name != null) {
    sql += " AND name = '" + name + "'";
}

⚠️ 缺点

  • SQL 注入风险
  • 难维护
  • 不推荐

✅ 正确方式(PreparedStatement):

String sql = "SELECT * FROM user WHERE 1=1";
if (name != null) {
    sql += " AND name = ?";
}

四、数据库存储过程中的动态 SQL

MySQL

SET @sql = 'SELECT * FROM user WHERE 1=1';
IF name IS NOT NULL THEN
  SET @sql = CONCAT(@sql, ' AND name = ''', name, '''');
END IF;

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

五、什么时候用动态 SQL?

✅ 适合:

  • 多条件查询
  • 可选参数
  • 批量操作
  • 动态表名 / 列名(慎用)

❌ 不适合:

  • 固定 SQL(性能更好)
  • 高频简单查询

六、常见坑 ⚠️

  1. SQL 注入

    • 不要字符串拼接
    • #{} 而不是 ${}
  2. ${} 和 #{} 区别

    • #{}:预编译 ✅
    • ${}:直接替换 ❌(只能用于表名/排序)
  3. 性能

    • 动态 SQL 可能影响索引使用

七、一句话总结

动态 SQL = 根据条件在运行时拼 SQL,MyBatis 是最常用、最安全的实现方式


如果你愿意,我可以:

  • ✅ 给你一个 完整 MyBatis 动态 SQL 示例
  • ✅ 对比 MyBatis vs Spring Data JPA
  • ✅ 讲 什么场景不该用动态 SQL

你现在是 MyBatis / JDBC / 存储过程 哪种场景?

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI