ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

springboot项目xml中#{}和${}

2026/8/13 22:39:34 拓冰建站 浏览量
springboot项目xml中#{}和${}

两者本质区别

  • ${params.id}:MyBatis 直接字符串替换,把值原样拼进 SQL。相当于字符串拼接。
  • #{params.id}:MyBatis 用 PreparedStatement 预编译占位符 ?,值由驱动单独传参,和 SQL 语句分离。

数字类型在数据库里会被自动转换,所以 #{} 对数字完全适用——数字和字符串都应该用 #{}

为什么 ${} 危险(即使是数字列)

以你原来 where id =${params.id} 为例:

-- 正常:id = 100
delete from sys_app_permission where id =100-- 攻击:id 传 "1 or 1=1"(虽然是 GET 参数,攻击者可以直接拼)
delete from sys_app_permission where id =1 or 1=1      -- 全表删光-- 攻击:id 传 "1; drop table xxx"
delete from sys_app_permission where id =1; drop table xxx

攻击者传的是字符串,不是数字。${} 不知道、也不关心你“本意”是数字,它只负责拼接,所以注入就发生了。

改成 #{} 后:

delete from sys_app_permission where id = ?   -- 参数 '1 or 1=1' 作为整体传给数据库

数据库把 '1 or 1=1' 当成 id 的值去匹配(数字列会转换失败报错,而不是执行注入),注入被彻底堵死

那什么时候必须用 ${}

只有 表名/字段名这类标识符才必须用 ${},因为 #{} 会给标识符加引号变成字符串值,SQL 不合法。

image