加载中...
加载中...
Mybatis井号#和美元$符号

Mybatis井号#和美元$符号 转载


Mybatis井号#和美元$符号

#{变量名}  

#{变量名}  可以进行预编译、类型匹配等操作,会转化为jdbc的类型。

select * from tablename where id = #{id}
假设id的值为12,其中如果数据库字段id为字符型,那么#{id}表示的就是'12',如果id为整型,那么id就是12,并且MyBatis会将上面SQL语句转化为jdbc的select * from tablename where id=?,把?参数设置为id的值。

${变量名}

${变量名}不进行数据类型匹配,直接替换。
select * from tablename where id = ${id}
如果字段id为整型,sql语句就不会出错,但是如果字段id为字符型, 那么sql语句应该写成select * from table where id = '${id}'。

#{变量名} 的方式能够很大程度防止sql注入。

${变量名} 方式无法方式sql注入。

${变量名}方式一般用于传入数据库对象,例如传入表名、列名。

尽量多用#方式,少用$方式。

#{变量名} 的方式为什么能防止sql注入?

Mybatis框架作为一款半自动化的持久层框架,其sql语句都要我们自己来手动编写,这个时候当然需要防止sql注入。其实Mybatis的sql是一个具有“输入+输出”功能,类似于函数的结构。
例 mapper.xml如下:
复制收展XML<select id="getBlogById" resultType="Blog" parameterType="int">
select id,title,author,content
from blog where id=#{id}
</select>
  • 1
  • 2
  • 3
  • 4

parameterType标示了输入的参数类型,resultType标示了输出的参数类型。如果我们想防止sql注入,理所当然地要在输入参数上下功夫。

上面代码中#{id}即输入参数在sql中拼接的部分,传入参数后,打印出执行的sql语句,会看到sql是这样的:

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

SQL注入攻击的原理

SQL注入是目前比较常见的针对数据库的一种攻击方式。在这种攻击方式中,攻击者会将一些恶意代码插入到字符串中。然后会通过各种手段将该字符串传递到SQL服务数据库的实例中进行分析和执行。只要这个恶意代码符合SQL语句的规则,则在代码编译与执行的时候,就不会被系统所发现。

SQL注入式攻击的主要形式有两种。
一是直接将代码插入到与SQL命令串联在一起并使得其以执行的用户输入变量。由于其直接与SQL语句捆绑,故也被称为直接注入式攻击法。
二是一种间接的攻击方法,它将恶意代码注入要在表中存储或者作为原数据存储的字符串。在存储的字符串中会连接到一个动态的SQL命令中,以执行一些恶意的SQL代码。

注入过程的工作方式是提前终止文本字符串,然后追加一个新的命令。以直接注入式攻击为例。用户输入变量的时候,先用一个分号结束当前的语句。然后再插入一个恶意SQL语句即可。由于插入的命令可能在执行前追加其他字符串,因此攻击者常常用注释标记“- -”来终止注入的字符串。执行时,系统会认为此后语句为注释,故后续的文本将被忽略,不被编译与执行。


在原文基础上增加修改了一些。

原文:https://blog.csdn.net/java1993666/article/details/54377036

MyBatis中文官网
http://www.mybatis.cn/archives/43.html  

没有更多推荐了 [去首页]
image
文章
357
原创
284
转载
73
翻译
0
访问量
199056
喜欢
47
粉丝
6
码龄
5年
资源
0

文章目录

加载中...
0
0