温馨提示×

温馨提示×

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

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

动态SQL安全吗

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

动态 SQL 本身并不“天然安全”,是否安全取决于你“怎么写”。
如果处理不当,它非常容易导致 SQL 注入,这是最常见、危害最大的安全问题之一。

下面从原理、风险、安全写法几个角度说明。


一、什么是动态 SQL

动态 SQL 指的是 SQL 语句在运行时拼接生成,而不是直接写死,例如:

SELECT * FROM user WHERE name = ' + userName + '

或:

"SELECT * FROM user WHERE id = " + id

二、动态 SQL 最大的风险:SQL 注入

示例(不安全)

String sql = "SELECT * FROM user WHERE name = '" + name + "'";

如果用户输入:

name = ' OR '1'='1

最终 SQL 变成:

SELECT * FROM user WHERE name = '' OR '1'='1'

直接查全表,甚至被删库


三、什么时候动态 SQL 是“安全的”

只要参数不拼 SQL,而是作为参数传入

1️⃣ 使用预编译(最推荐)

Java(JDBC / MyBatis)

PreparedStatement ps =
    conn.prepareStatement("SELECT * FROM user WHERE name = ?");
ps.setString(1, name);

安全

  • 参数值不会被当成 SQL 执行
  • 数据库会自动转义

2️⃣ MyBatis 动态 SQL(正确用法)

✅ 安全:

<select id="findUser">
  SELECT * FROM user
  <where>
    <if test="name != null">
      AND name = #{name}
    </if>
  </where>
</select>

❌ 不安全(字符串拼接):

AND name = '${name}'

结论:MyBatis 中 #{} 安全,${} 危险


四、动态 SQL 安全的 4 条铁律 ✅

  1. 永远不要字符串拼接用户输入
  2. 优先使用预编译(PreparedStatement / ORM)
  3. 动态条件用参数占位符,而不是拼 SQL
  4. 如果必须拼表名 / 字段名,必须白名单校验

五、哪些场景“必须”动态 SQL?

✅ 合理且安全的使用场景:

  • 条件可选(搜索、筛选)
  • 动态排序(ORDER BY)
  • 动态表名(分表)

⚠️ 表名 / 排序字段 不能参数化,只能:

  • 白名单校验
  • 枚举控制
if ("create_time".equals(sortField)) {
    sql += " ORDER BY create_time";
}

六、一句话总结

动态 SQL 本身不是问题,拼 SQL 才是问题。
参数化 = 安全,拼接 = 高危。

如果你愿意,可以把你现在的 SQL 或代码贴出来,我可以帮你判断 是否安全、如何改

向AI问一下细节

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

AI