MyBatis Tips:#与$的区别

最近开发的时候遇到了一些问题,我在做一个Oracle转SQL Server的项目时,遇到了MyBatis中对于SQL语句转义的疑惑,经过学习,整理如下。

1,MyBatis中的 # 与 $ 的区别

其实,区别就是如果使用#{}#,会将{}里面的传入的值自动解析成为带引号的值,比如:

select count(1) from t_user where user_name = #{userName} and user_pwd = #{userPassword}

假如,此时传入user_name传入的值为admin,user_pwd传入的值为123456,那么最后的SQL就是:

select count(1) from t_user where user_name = 'admin' and user_pwd = '123456';

会解析成字符串,而${}就会这样解析:

select count(1) from t_user where user_name = admin and user_pwd = 123456;

这个SQL语句在SQL Server中是可行的,然而到了Oracle就变成了错误语句,此为第一处区别。另外#{}可以有效的防止SQL注入,那么什么是SQL注入呢?

2,什么是SQL注入?

SQL注入就是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库执行一些恶意的操作

比如说,在登录过程中,利用上面的语句到数据库中查找用户名/密码是否存在,如果存在就登录成功

而如果不存在就登录失败,如果说你后台使用的是${},恶意用户在表单中的用户名文本框中输入的是’admin’

密码框中输入的是’ ’ or 1 = 1 加了一引号和一个恒成立的条件,那么,传到数据库中的SQL就是:

select count(1) from t_user where user_name = 'admin' and user_pwd = ' ' or 1=1

如果程序没有做其他的校验,此时,该恶意用户是可以登录系统的。 这就是SQL注入,恶意攻击

而使用#{}是不会出现这种情况的,#{}默认会给输入的值加上引号,这样转义之后的SQL语句就是:

select count(1) from SSB_USER where user_name = 'admin' and user_pwd = ''' or 1=1'

但是使用#{}在动态场景下并不适用,比如要使用到排序 order by #{} 传入的参数应是表对应字段名,但是加上引号后就会解析成 order by ‘xxx’

这样就达不到排序的目的,而此时如果使用${}就可以达到排序的目的,即,SQL解析成 order by xxx,根据xxx排序。

猜你喜欢

转载自blog.csdn.net/taxuteng/article/details/85229242