1、#{}
将传入的数据当作一个字符串,会对传入的数据加上一个双引号。
比如:
select * from student where student_name = #{studentName}
如果传入的值为zhangsan
,那么经过Mybatis
解析完成之后的语句是:
select * from student where student_name="zhangsan"
2、${}
将传入的数据直接显示生成在sql
中。
比如:
select ${fieldName} from user where user_age = 22
此时,传入的参数作为要查询的字段,如果传入的值为user_name
,则解析成的sql
为:
select user_name from user where user_age = 22
#{}
方式能够很大程度上防止sql
注入,${}
无法防止sql
注入。
${}
方式一般用于传入数据库对象,例如列表和表名,#{}
方式一般用来传递接口传输过来的具体数据。
由于#{}
方式具有更高的安全行,所以能用#{}
的地方尽量不要使用${}
。
Mybatis
排序时使用order by
动态参数时需要注意,用${}
而不是#{}
。
#
符号(Pound Sign
):
#
符号用于参数值的占位,会将参数值进行预编译,并在执行SQL
语句时将参数值安全地传递给数据库,防止SQL
注入攻击。
适用于大多数情况,尤其是当参数值来自用户输入或不可信数据时,是更安全的选择。
参数值会被自动转义,不需要担心特殊字符的处理。
使用#
符号会产生预编译的SQL
语句,可以提高数据库的性能,因为数据库可以缓存相同的预编译语句。
<!-- 使用#符号进行参数占位 -->
<select id="getUserById" parameterType="int" resultType="User">
SELECT * FROM users
WHERE id = #{userId}
</select>
$
符号(Dollar Sign
):
$
符号用于简单的值替换,不进行预编译,直接将参数的值嵌入SQL
语句中。
适用于那些不需要参数值预编译,且参数值是确定且可信的情况,比如用于动态拼接SQL
语句的情况。
使用$
符号时,需要小心防止SQL
注入攻击,需要手动处理参数值的安全性。
不会产生预编译的SQL
语句,可能会导致数据库性能较低,因为每次SQL
语句都会重新解析和执行。
<!-- 使用$符号进行简单值替换 -->
<select id="getUserByName" parameterType="string" resultType="User">
SELECT * FROM users
WHERE username = '${username}'
</select>
$
动态 拼接SQL
下面是一个实例:
<select id="getUsersWithDynamicSorting" parameterType="map" resultType="User">
SELECT * FROM users
WHERE 1=1 <!-- 为了方便拼接,可以始终使用一个始终成立的条件 -->
<!-- 根据参数动态拼接排序字段和排序顺序 -->
<if test="sortField != null and sortOrder != null">
ORDER BY ${sortField} ${sortOrder}
</if>
</select>