Mybatis的#{}占位符与${}字符串替换的区别

1、#{}是预编译处理,$ {}是字符串替换

(1)#{} 表示一个占位符,采用preparedStatement给占位符设置值,自动进行java类型和jdbc类型转换,进行预编译处理,#{}可以有效防止sql注入(预编译是提前对SQL语句进行编译,而其后注入的参数将不会再进行编译)

(2)${} 表示字符串替换,通过${}可以将parameterType或实体 传入的内容拼接在sql中且不进行jdbc类型转换

(3)举例说明二者区别,现在有如下SQL:

select count(1) from user where user_name = #{userName} and password = #{password}

使用#{}时,会进行jdbc类型转换,根据属性 自动加上单引号

select count(1) from user where user_name = 'admin' and password = '123456';

而${}不会进行jdbc类型转换,只是简单的替换, 显然有语法错误,但是可以利用其进行sql注入

select count(1) from user where user_name = admin and password = 123456;

2、SQL注入举例离说明

SQL注入就是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库执行一些恶意的操作。比如说,在登录过程中,利用上面的语句到数据库中查找用户名/密码是否存在,如果存在就登录成功,如果不存在就登录失败。

若使用${},恶意用户在表单中的用户名文本框中输入的是'admin',密码框中输入的是 ' ' or 1 = 1 加了一引号和一个恒成立的条件,那么,传到数据库中的sql就是:

select count(1) from user where user_name = 'admin' and user_password = ' ' or 1=1

登录成功,该恶意用户是可以登录系统的! 这就是SQL注入,恶意攻击

而如果使用#{}是不会出现这种情况的,#{}默认会给输入的值加上引号,密码错误,登录失败

select count(1) from user where user_name = ''admin'' and user_password ='' ' or 1=1'

3、既然有了#{}为什么还需要${}

#{}并不适用一些其他场景,比如要根据参数名动态排序,需要传入的参数是字段名,使用#{} 被解析成order by 'age' ,显然达不到排序目的。而此时就用到了${}进行字符串替换操作,即sql解析成 order by age

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值