在 MyBatis 中,#{}
和 ${}
都是用于动态 SQL 语句中的占位符,但是它们的作用和使用方式是不同的。下面是它们的区别:
1. #{}
—— 用于防止 SQL 注入和自动类型处理
#{}
是用来将参数安全地传递到 SQL 语句中,它会将传递的参数值进行预编译,并使用 JDBC 的 PreparedStatement 设置参数值。- 通过
#{}
插入的参数会经过 MyBatis 的类型处理器自动转换成数据库支持的类型。 #{}
还会避免 SQL 注入,因为它会把参数值作为参数传递,而不是直接拼接到 SQL 中。
示例代码:
<select id="selectUser" resultType="User">SELECT * FROM user WHERE id = #{userId}
</select>
在这个例子中,#{userId}
会被 MyBatis 处理成一个安全的参数传递给 SQL,而不是将 userId
的值直接拼接到 SQL 语句中。这样可以避免 SQL 注入攻击。
2. ${}
—— 直接拼接字符串到 SQL 中
${}
是用于将参数直接拼接到 SQL 语句中的占位符。它不会做任何的预处理或者类型转换,而是将参数的值直接插入到 SQL 语句中。- 使用
${}
时需要小心,因为如果传入的参数是由用户输入的,不加以处理就会导致 SQL 注入攻击。
示例代码:
<select id="selectUser" resultType="User">SELECT * FROM user WHERE ${columnName} = #{value}
</select>
在这个例子中,${columnName}
会直接拼接到 SQL 语句中,这样可以动态地选择不同的列进行查询。如果传入的 columnName
由用户输入,可能会造成 SQL 注入风险。因此,使用 ${}
时需要非常小心,确保不会将不安全的内容拼接到 SQL 语句中。
总结:
#{}
:用于安全地传递参数,防止 SQL 注入,同时进行参数的类型转换。一般推荐在 SQL 查询中使用#{}
。
止 SQL 注入,同时进行参数的类型转换。一般推荐在 SQL 查询中使用#{}
。${}
:将参数直接拼接到 SQL 语句中,可能会带来 SQL 注入的风险。通常用于动态生成列名、表名等不容易被参数化的内容。