MyBatis入门十二:预防SQL注入攻击;(${}和#{}的区别)

本篇博客的内容不多,就一条:大部分情况下,使用#{}预编译的手段,而不是用${}原文传值。 

 目录

0.SQL注入攻击简介   &   #{}和${}简介

1.使用${}原文传值这种取值方式:

2.使用#{}预编译这种取值方式:

3.So,#{}预编译这种方式这么给力,为什么还需要${}原文传值这种方式嘞?


0.SQL注入攻击简介   &   #{}和${}简介

MyBatis入门十二:预防SQL注入攻击;(${}和#{}的区别)_第1张图片

具体可参考:JDBC入门六:SQL注入攻击:什么是SQL注入攻击?;Java中引号嵌套的分析;

在实际应用中,在前台用户输入的时候,输入内容带有很大的随意性,其输入内容可能不当;然后,在后台输入项并没有对单引号等特殊字符进行转义等操作;因此,在前端页面上输入的包含单引号等特殊字符的字符串,作为SQL的一部分被带入到了SQL语句中被执行,就可能会造成数据泄露。

JDBC中采用JDBC入门七:SQL注入攻击:SQL注入攻击的解决策略:PreparedStatement预编译SQL;来解决SQL注入攻击问题。

但是,在mybatis中并不需要手动开发,mybatis已经帮我们封装好了:

MyBatis入门十二:预防SQL注入攻击;(${}和#{}的区别)_第2张图片

(1)${}原文传值这种取值方式,特别像JSP中的EL表达式;;但是,在mybatis中不推荐使用这种方式;;${}这种方式:原始字符串在不经过任何处理的情况下,对SQL文本进行替换;即,这种方式取得值会被当成SQL子句;

(2)#{}预编译方式:推荐使用这种方式,(前面的案例中,也都是使用的这种取值方式)。。。#{}:预编译传值,其会对字符串中的特殊字符进行转义处理;;使用预编译传值可以有效的预防SQL注入攻击。(PS:mybatis封装了JDBC,挺好用的~~~)即,这种方式取得值会被整体当成一个字符串;


 

1.使用${}原文传值这种取值方式:

MyBatis入门十二:预防SQL注入攻击;(${}和#{}的区别)_第3张图片

正常调用的时候:

MyBatis入门十二:预防SQL注入攻击;(${}和#{}的区别)_第4张图片

但是,如果做点手脚:就会看到SQL注入攻击的效果。

MyBatis入门十二:预防SQL注入攻击;(${}和#{}的区别)_第5张图片


 

2.使用#{}预编译这种取值方式:

MyBatis入门十二:预防SQL注入攻击;(${}和#{}的区别)_第6张图片

此时,不再有SQL注入攻击的效果了。

MyBatis入门十二:预防SQL注入攻击;(${}和#{}的区别)_第7张图片


 

3.So,#{}预编译这种方式这么给力,为什么还需要${}原文传值这种方式嘞?

${}原文传值也有对应的使用场景:

比如,希望根据前台输入的条件不同,来选择不同的字段进行排序。这种场景就需要使用${}原文传值来动态变化SQL了。

即,当需要动态的改变goods.xml中的SQL语句时,,,就需要在java程序调用goods.xml的SQL标签时传入不同的参数,而这个不同的参数是需要被解析成SQL语句的,而不是被解析成一个字符串,,,所以此时需要使用${},而不能使用#{}。。。。。

MyBatis入门十二:预防SQL注入攻击;(${}和#{}的区别)_第8张图片

但是,在实际中还是不建议使用${}原文传值,因为这种如果一不小心就可能出现SQL注入攻击的风险。同时,在日常开发中,绝大部分情况下使用#{}预编译就够了。。。

但是,如果在项目中遇到一些高级的特性,必须要进行SQL拼接的话,就要使用${}原文传值了,但是此时,${}中间的SQL子句,绝对不能是外界输入的(而是,在程序中写好,然后根据前台不同的输入,去调用不同的、在程序中写好的那些SQL子句;;;因为前台的输入太随意了,在程序中定义好更靠谱。。。因此,在程序中需要额外编写一套逻辑,根据前台输入的不同,去调用程序中写好的不同的SQL子句)。。。然后,在实际编写的时候,可能需要一些编程的小技巧,让程序更加优雅和稳固!!!!


 

你可能感兴趣的:(Mybatis)