MyBatis中#{}和${}的用法


说一下为什么要写这篇文章,最近面试有被问到,一下子想不出来有啥区别,想记录一下加深自己的理解,同时自己也经常用MyBatis-Plus忽略了XML文件的编写和使用,所以需要加深一下这块的知识

一、例子

1、#{}将传入的数据当作一个字符串,会对传入的数据加上一个双引号。

比如

select * from student where student_name = #{studentName}

如果传入的值为zhangxiangwei,那么经过Mybatis解析完成之后的语句是

select * from student where student_name="zhangxiangwei"

2.${}将传入的数据直接显示生成在sql中。

比如

select ${fieldName} from user where user_age = 22

此时,传入的参数作为要查询的字段,如果传入的值为user_name,则解析成的sql为:

select user_name from user where user_age = 22

二、区别

1.#{}方式能够很大程度上防止sql注入,${}无法防止sql注入。

2.${}方式一般用于传入数据库对象,例如列表和表名,#{}方式一般用来传递接口传输过来的具体数据。

3.由于#{}方式具有更高的安全行,所以能用#{}的地方尽量不要使用${}。

4.Mybatis排序时使用order by动态参数时需要注意,用${}而不是#{}。

5.#符号(Pound Sign)

  • #符号用于参数值的占位,会将参数值进行预编译,并在执行SQL语句时将参数值安全地传递给数据库,防止SQL注入攻击。

  • 适用于大多数情况,尤其是当参数值来自用户输入或不可信数据时,是更安全的选择。

  • 参数值会被自动转义,不需要担心特殊字符的处理。

  • 使用#符号会产生预编译的SQL语句,可以提高数据库的性能,因为数据库可以缓存相同的预编译语句。

  •   SELECT * FROM users  WHERE id = #{userId}

6.$符号(Dollar Sign)

  • $符号用于简单的值替换,不进行预编译,直接将参数的值嵌入SQL语句中。

  • 适用于那些不需要参数值预编译,且参数值是确定且可信的情况,比如用于动态拼接SQL语句的情况。

  • 使用$符号时,需要小心防止SQL注入攻击,需要手动处理参数值的安全性。

  • 不会产生预编译的SQL语句,可能会导致数据库性能较低,因为每次SQL语句都会重新解析和执行。

  •   SELECT * FROM users  WHERE username = '${username}'

三、最后说一下 $ 动态 拼接SQL

下面是一个实例

  SELECT * FROM users  WHERE 1=1         ORDER BY ${sortField} ${sortOrder}