mybatis中#和$的区别 SQL

在mybatis中的$与#都是在sql中动态的传入参数。
eg:select id,name,age from student where name=#{name} 这个name是动态的,可变的。当你传入什么样的值,就会根据你传入的值执行sql语句。

两者区别

  1. 就是将传入的值作为字符串的形式。用#{}传入值,sql动态解析为一个JDBC预编译语句(preparedStatement)的参数标记符,也就是说,sql语句中如果存在参数则会使用?作占位符,加了单引号,把参数默认为字符串进行处理;

"select name from user where id= ?"
  1. $是将传入的数据直接显示生成sql语句,sql动态解析时候不加引号,直接进行变量替换,参与SQL编译。
  2. 使用#可以防注入。注入就是恶意的语句拼接。
  3. 使用order by中需要使用$
  4. 在parameterType是int时,sql语句中必须是#{}。

啥叫防注入?

SQL注入起因

SQL注入是一种常见的攻击方式,攻击者或者误操作者通过表单信息或者URL输入一些异常的参数(最常用的是使用字符串连接的方式组合SQL指令),传入服务端进行SQL处理,可能会出现这样的情况

delete from app_poi where poi_id = (输入参数):

输入参数:10 or 1 = 1

SQL拼接:delete from app_poi where poi_id = (10 or 1 = 1)

执行结果:app_poi中的所有数据都会被delete

例子2:
在这里插入图片描述
这种问题出现的原因可能是攻击者故意为之,也可能是误操作,那么服务端该如何处理,避免这样的问题出现呢?

mybatis防注入

其实就是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。

PreparedStatement会对SQL中输入的参数进行检测,并在SQL都是用问号来设置占位符,即只允许传入一个参数,像(10 or 1 = 1)这种明显不会被占位符所接受。

因为SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注入的问题。

结论

so,#{}是经过预编译的,是安全的; 是 未 经 过 预 编 译 的 , 仅 仅 是 取 变 量 的 值 , 非 安 全 的 。 如 果 不 得 不 使 用 {}是未经过预编译的,仅仅是取变量的值,非安全的。如果不得不使用 使{}那么要手工做好过滤工作。

关于注入的例子见:https://blog.csdn.net/qq_27811247/article/details/80775036

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值