Mybatis中 ${} 和 #{} 的区别
文章目录
- 引言
- 一、${} 占位符
- 二、#{} 占位符
- 三、SQL 注入
- 错误做法
- 正确做法
- 占位符总结
引言
MyBatis 作为一款流行的 ORM 框架,其主要用于映射数据库操作和 Java 对象。在 MyBatis 中,${} 和 #{} 都是用于处理 SQL 动态内容的占位符,但它们的功能和用途有所不同。
一、${} 占位符
${} 占位符是 Mybatis 中的字符串替换占位符,实际上就是拼接字符串,但是如果参数值来自用户输入,容易受到 SQL 注入攻击,使用时要小心。
二、#{} 占位符
#{} 占位符是Mybatis中的参数占位符,MyBatis 会将 sql 中的 #{} 替换为 ? 号,用于防止 SQL 注入,执行时会被替换为参数值并通过 PreparedStatement (预编译语句)传递给数据库。
三、SQL 注入
错误做法
在 MyBatis 中,${} 会直接将参数的值拼接到 SQL 语句中,比如此时用户正在登录,SQL 语句如下:
SELECT * FROM user WHERE username = '${username}'
但由于用的是 ${},此时可以进行字符串拼接,最终 SQL 语句会变成:
SELECT * FROM user WHERE username = 'admin' OR '1'='1'
OR ‘1’=‘1’ 始终为真,这意味着查询会返回 user 表中的所有数据,而不仅仅是 admin 用户。
正确做法
使用 #{},因为它会使用 PreparedStatement 进行参数绑定,避免 SQL 注入:
SELECT * FROM user WHERE username = #{username}
在这种情况下,即使用户输入 admin’ OR ‘1’='1,SQL 语句仍然是:
SELECT * FROM user WHERE username = ?
然后 MyBatis 会将 username 的值作为参数传递给数据库,而不是直接拼接到 SQL 语句中。这样即使用户输入 OR ‘1’='1,恒为真不会影响到原 SQL 语句,从而有效防止 SQL 注入攻击。
占位符总结
方式 | 安全性 | 说明 |
---|---|---|
${} | 不安全 | 直接拼接 SQL,容易被 SQL 注入攻击利用 |
#{} | 安全 | 通过预编译的方式传递参数,防止 SQL 注入 |