温馨提示×

温馨提示×

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

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

动态SQL用在哪些场景

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

动态 SQL 主要用于SQL 语句的结构或条件在运行时才能确定的场景,常见于业务复杂、查询条件不固定、对象结构可变等情况。下面按典型场景 + 示例说明来总结。


一、常见使用场景

1️⃣ 多条件组合查询(最常见)

场景特点
查询条件由用户选择,可能传、也可能不传。

示例
用户查询订单,可选条件:

  • 订单号
  • 用户ID
  • 订单状态
  • 时间范围

SQL 示例(MyBatis)

<select id="queryOrders" resultType="Order">
  SELECT * FROM orders
  <where>
    <if test="orderNo != null">
      AND order_no = #{orderNo}
    </if>
    <if test="userId != null">
      AND user_id = #{userId}
    </if>
    <if test="status != null">
      AND status = #{status}
    </if>
    <if test="startTime != null">
      AND create_time >= #{startTime}
    </if>
  </where>
</select>

避免写大量 if-else 拼接 SQL


2️⃣ 动态排序(ORDER BY)

场景特点
排序字段、排序方式由前端或参数决定。

示例

<select id="queryUsers">
  SELECT * FROM user
  ORDER BY
  <choose>
    <when test="sortBy == 'age'">age</when>
    <when test="sortBy == 'name'">name</when>
    <otherwise>id</otherwise>
  </choose>
  <if test="order == 'desc'">DESC</if>
</select>

3️⃣ 动态更新字段(UPDATE)

场景特点
只更新用户传过来的字段,不更新 null 字段。

示例

<update id="updateUser">
  UPDATE user
  <set>
    <if test="name != null">name = #{name},</if>
    <if test="age != null">age = #{age},</if>
    <if test="email != null">email = #{email},</if>
  </set>
  WHERE id = #{id}
</update>

✅ 避免把字段更新成 null


4️⃣ 动态插入(INSERT)

场景特点
插入字段不固定,比如不同业务类型字段不同。

示例

<insert id="insertUser">
  INSERT INTO user
  <trim prefix="(" suffix=")" suffixOverrides=",">
    id,
    <if test="name != null">name,</if>
    <if test="age != null">age,</if>
  </trim>
  VALUES
  <trim prefix="(" suffix=")" suffixOverrides=",">
    #{id},
    <if test="name != null">#{name},</if>
    <if test="age != null">#{age},</if>
  </trim>
</insert>

5️⃣ IN 查询(参数数量不固定)

场景特点
ID 列表、状态列表等动态变化。

示例

<select id="queryByIds">
  SELECT * FROM user
  WHERE id IN
  <foreach collection="ids" item="id" open="(" close=")" separator=",">
    #{id}
  </foreach>
</select>

6️⃣ 分表 / 分库场景

场景特点
表名、库名在运行时决定。

示例

<select id="queryLog">
  SELECT * FROM log_${tableSuffix}
  WHERE id = #{id}
</select>

⚠️ 注意:${} 有 SQL 注入风险,需严格校验参数


7️⃣ 动态 JOIN

场景特点
是否连表由条件决定。

示例

SELECT u.*
FROM user u
<if test="needOrder">
  LEFT JOIN orders o ON u.id = o.user_id
</if>

8️⃣ 权限 / 数据隔离

场景特点
根据用户角色、部门动态拼接条件。

示例

<if test="role == 'MANAGER'">
  AND department_id = #{departmentId}
</if>
<if test="role == 'ADMIN'">
  <!-- 不限制 -->
</if>

二、什么时候不该用动态 SQL?

不推荐场景

  • 固定 SQL(直接写死更清晰)
  • 高频简单查询(动态 SQL 有解析成本)
  • 参数不可信却使用 ${}(SQL 注入)

三、主流框架中的动态 SQL

框架 动态 SQL 方式
MyBatis XML / 注解 <if> <foreach>
JPA / Hibernate Criteria API、Specification
Spring JDBC 手动拼接(不推荐)
MyBatis-Plus Lambda / Wrapper

四、一句话总结

只要 SQL 的“条件、字段、表名、结构”在运行时才能确定,就适合用动态 SQL。

如果你愿意,我可以:

  • 对比 MyBatis vs JPA 动态 SQL
  • 给你一个 真实业务案例
  • 帮你判断 某个场景是否适合用动态 SQL
向AI问一下细节

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

AI