面试题:mybatis中# 和 $ 的区别
一、主要区别如下:
1、#{}可以理解为预处理,而${}是直接替换。
#传入的参数在SQL中显示为字符串,会对自动传入的数据加上双引号。
$传入的参数在SQL中直接显示为传入的值
2、#{}试用于所有类型的参数匹配,但${}只试用于数值类型
这个很好理解因为使用#{}传入的参数会以字符串的形式进行匹配,而${}传入的参数则是直接替换,数值类型你像Id这种直接替换还好,如果是字符Name这种传入一个名字直接替换的话就会出错。
3、#{}性能更高,并且没有SQL注入的安全性问题,但${}存在SQL注入的安全问题
4、大多数情况下还是经常使用#{},一般能用#的就别用$ ,但是有些情况下必须使用$ ,例如:MyBatis排序时,使用order by动态参数时候需要注意,用$ 而不是#。
二、详细分析一下子(看好了!!!)
1.1 如下的SQL语句,使用#{}传入name字段,根据name查询
<select id="getUserByName" resultMap="UserMap">select * from mybatis.user where name = #{Name}</select>
上述的SQL语句解析后内容如下:
好,,我们可以从下图中看到使用#{}传入的name参数,其在解析后生成的SQL语句是预处理、预先占领然后传入了String类型的这样一个参数的效果。
1.2 于此相对,上述的SQL语句,我们使用${} 传入name字段
<select id="getUserByName" resultMap="UserMap">select * from mybatis.user where name = ${Name}</select>
上述的SQL语句解析后内容如下:
我们可以很清楚的看到,使用 $ 这种方式是将我们的传入的参数直接替换到对应的SQL语句中,这样不仅会导致SQL注入的问题,而且很明显是怎么样,,错误的(因为使用$ {} 它没有对你传入的参数进行预处理,只是单纯的替换,那肯定不行,应该处理为String类型的数据,这也说明了为什么#{}试用于各种传入的数据类型的参数)。
因此,使用$ 只有当传入的数据类型为整数或是特定的场景下时(比如MyBatis排序时,使用order by动态参数时候需要注意,用$ 而不是#)才是合适的。