2016 - 2024

感恩一路有你

java常用的消息队列 浅谈mybatis中的#和$的区别,以及防止sql注入的方法?

浏览量:3073 时间:2021-03-12 05:58:28 作者:admin

浅谈mybatis中的#和$的区别,以及防止sql注入的方法?

#{ } 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符。

例如,sqlMap 中如下的 sql 语句

select * from user where name = #{name}

解析为:

select * from user where name = ?

一个 #{ } 被解析为一个参数占位符 ? 。

${ } 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换

例如,sqlMap 中如下的 sql

select * from user where name = "${name}"

当我们传递的参数为 "ruhua" 时,上述 sql 的解析为:

select * from user where name = "ruhua"

预编译之前的 SQL 语句已经不包含变量 name 了。

综上所得, ${ } 的变量的替换阶段是在动态 SQL 解析阶段,而 #{ }的变量的替换是在 DBMS 中。

注意:${ } 在预编译之前已经被变量替换了,这会存在 sql 注入问题。

MyBatis怎么防止SQL注入?

用#{参数}进行预编译就可以防止了,千万别用${}这种方式注入参数。

mybatis框架作为一款半自动化的持久层框架,其sql语句都要我们自己来手动编写,这个时候当然需要防止sql注入。其实Mybatis的sql是一个具有“输入 输出”功能,类似于函数的结构,如下:

select id,title,author,content

from blog where id=#{id}

这里,parameterType标示了输入的参数类型,resultType标示了输出的参数类型。回应上文,如果我们想防止sql注入,理所当然地要在输入参数上下功夫。上面代码中高亮部分即输入参数在sql中拼接的部分,传入参数后,打印出执行的sql语句,会看到sql是这样的:

select id,title,author,content from blog where id = ?

不管输入什么参数,打印出的sql都是这样的。这是因为mybatis启用了预编译功能,在sql执行前,会先将上面的sql发送给数据库进行编译,执行时,直接使用编译好的sql,替换占位符“?”就可以了。因为sql注入只能对编译过程起作用,所以这样的方式就很好地避免了sql注入的问题。

mybatis为什么可以防止sql注入?

因为在mybatis中,”${xxx}”这样格式的参数会直接参与sql编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式,所以,这样的参数需要程序开发者在代码中手工进行处理来防止注入。#xxx# 代表xxx是属性值,map里面的key或者是你的pojo对象里面的属性, ibatis会自动在它的外面加上引号,表现在sql语句是这样的 where xxx = "xxx" $xxx$ 则是把xxx作为字符串拼接到sql语句中, 比如 order by topicId , 语句这样写 ... order by #xxx# ibatis 就会翻译成order by "topicId" (这样就会报错) 语句这样写 ... order by $xxx$ ibatis 就会翻译成 order by topicId

浅谈mybatis中的#和$的区别以及防止sql注入的方法?

Mybatis本身是基于JDBC封装的。

#{para}是预编译处理(PreparedStatement)范畴的。

${para}是字符串替换。

Mybatis在处理#时,会调用PreparedStatement的set系列方法来赋值;处理$时,就是把${para}替换成变量的值。

使用#{para}可以有效的防止SQL注入,提高系统安全性。

java常用的消息队列 java三种队列详解 java实现消息队列的两种方式

版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。