mybatis中#{}和${}的区别

1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,若是传入的值是111,那么解析成sql时的值为order by "111", 若是传入的值是id,则解析成的sql为order by "id".
  
2. $将传入的数据直接显示生成在sql中。如:order by $user_id$,若是传入的值是111,那么解析成sql时的值为order by user_id,  若是传入的值是id,则解析成的sql为order by id.
  
3. #方式可以很大程度防止sql注入。
  
4.$方式没法防止Sql注入。

5.$方式通常用于传入数据库对象,例如传入表名.
  
6.通常能用#的就别用$.

MyBatis排序时使用order by 动态参数时须要注意,用$而不是#

字符串替换
默认状况下,使用#{}格式的语法会致使MyBatis建立预处理语句属性并以它为背景设置安全的值(好比?)。这样作很安全,很迅速也是首选作法,有时你只是想直接在SQL语句中插入一个不改变的字符串。好比,像ORDER BY,你能够这样来使用:
ORDER BY ${columnName}
这里MyBatis不会修改或转义字符串。sql

重要:接受从用户输出的内容并提供给语句中不变的字符串,这样作是不安全的。这会致使潜在的SQL注入攻击,所以你不该该容许用户输入这些字段,或者一般自行转义并检查。数据库

 

mybatis自己的说明:安全

复制代码
String Substitution

By default, using the #{} syntax will cause MyBatis to generate PreparedStatement properties and set the values safely against the PreparedStatement parameters (e.g. ?). While this is safer, faster and almost always preferred, sometimes you just want to directly inject a string unmodified into the SQL Statement. For example, for ORDER BY, you might use something like this:

ORDER BY ${columnName}
Here MyBatis won't modify or escape the string.

NOTE It's not safe to accept input from a user and supply it to a statement unmodified in this way. This leads to potential SQL Injection attacks and therefore you should either disallow user input in these fields, or always perform your own escapes and checks.
复制代码

从上文能够看出:mybatis

1. 使用#{}格式的语法在mybatis中使用Preparement语句来安全的设置值,执行sql相似下面的:this

PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,id);

这样作的好处是:更安全,更迅速,一般也是首选作法。spa

2. 不过有时你只是想直接在 SQL 语句中插入一个不改变的字符串。好比,像 ORDER BY,你能够这样来使用:code

ORDER BY ${columnName}

此时MyBatis 不会修改或转义字符串。orm

这种方式相似于:对象

    Statement st = conn.createStatement();
       
      ResultSet rs = st.executeQuery(sql);

这种方式的缺点是: 以这种方式接受从用户输出的内容并提供给语句中不变的字符串是不安全的,会致使潜在的 SQL 注入攻击,所以要么不容许用户输入这些字段,要么自行转义并检验。blog