温馨提示×

温馨提示×

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

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

动态SQL怎么写更安全

发布时间:2026-09-29 11:30:32 来源:亿速云 阅读:105 作者:小樊 栏目:数据库

在写动态 SQL 时,“安全”主要指的是:防止 SQL 注入、避免语法错误、便于维护和排查问题。下面从原则、写法和常见框架示例来说。


一、核心安全原则(最重要)

✅ 1. 永远不要拼接用户输入到 SQL 中

❌ 错误示例(极其危险):

"SELECT * FROM user WHERE name = '" + username + "'"

✅ 正确做法:使用参数化查询(占位符)


二、安全的动态 SQL 写法

✅ 2. 使用参数化(PreparedStatement / 占位符)

无论是否动态,都只拼 结构,不拼 值。

SELECT * FROM user
WHERE 1=1
  AND name = ?
  AND age > ?

✅ 3. 动态条件只拼“列名 / 逻辑”,不拼“值”

可以动态拼接:

  • 表名(谨慎)
  • 字段名(白名单)
  • WHERE 条件结构

不能动态拼接值


✅ 4. 对“非参数化部分”做白名单校验

比如排序字段:

❌ 危险:

ORDER BY ${column}

✅ 安全:

List<String> allowed = Arrays.asList("id", "name", "create_time");
if (!allowed.contains(column)) {
    column = "id";
}

三、MyBatis 中的安全动态 SQL(常见)

✅ 使用 <if> + #{}

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

✅ #{} → 预编译参数(安全)
❌ ${} → 字符串替换(危险,仅用于白名单)


✅ ORDER BY 安全写法

<if test="sortField == 'name' or sortField == 'id'">
  ORDER BY ${sortField}
</if>

或 Java 中控制:

if (!ALLOWED.contains(sortField)) sortField = "id";

四、Spring / JPA 中的安全方式

✅ JPA Criteria / QueryDSL

CriteriaBuilder cb = ...
Predicate p = cb.equal(root.get("name"), name);

✅ JdbcTemplate

jdbcTemplate.query(
  "SELECT * FROM user WHERE name = ?",
  name
);

五、其他安全建议

  • ✅ 最小权限数据库账号
  • ✅ 关闭错误信息直接返回给前端
  • ✅ 限制动态 SQL 的复杂度
  • ✅ 日志中不要打印参数值(防泄露)

六、一句话总结

动态 SQL 安全 = 结构可动态 + 值必须参数化 + 非值部分白名单

如果你用的是 MyBatis / JPA / 原生 JDBC / Python / Go,我可以给你对应语言的具体模板。

向AI问一下细节

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

AI
助
手