- MyBatis 在处理 #{} 时,会将 SQL 中的 #{} 替换为 ?,预编译 SQL,通过 PreparedStatement 的 setXxxx 的方法进行参数赋值。使用 #{} 可以有效地防止 SQL 注入。
- MyBatis 在处理 ${} 时,会直接把 ${} 替换为参数值,存在 SQL 注入的风险。
- #{} 比 ${} 安全,但还是提供了 ${} 这种动态替换参数的方式,是因为有些复杂的 SQL 使用场景通过预编译的方式比较麻烦,且在代码中完全可以做到控制非法参数,有些参数可能是一些常量或字段值。
PS:
SQL 注入是在编译的过程中,注入了某些特殊的恶意 SQL 片段,被编译成了恶意的 SQL 执行操作。
预编译是提前对 SQL 进行编译,后面注入的参数不会对 SQL 的结构产生影响,从而避免安全风险。