关于prepareStatement可以防止SQL注入的理解

prepareStatement的两个作用:

1. 预处理功能,在多次执行相同的SQL语句并且只是更换了参数(例如表名,字段名)的情况可以大幅提高执行效率;

例如: 

    select name from table_student.

    select sex from table_student.

    select number from table_teacher.

类似的语句多次执行,这样的情况就可以通过preparestatement简化为select ? from ?,然后后面填参数替换掉符号?   当然这只是提高效率,重点介绍第二条。


2. 杜绝SQL注入的风险

简单介绍一下SQL注入的原理:

关于prepareStatement可以防止SQL注入的理解

那么我们如何防止呢,prepareStatement的作用就是将上图中的 Name, Password, Corp参数化处理,那么就要将服务器端代码改为如下的样子:

    String sql = "select * from Table where name =? and Password = ? and Corp = ? ";  

    PreparedStatement prep = conn.prepareStatement(sql);  

    prep.setString(1, name_input);  

    prep.setString(2, pwd_input);  

    prep.setString(3, corp_input);  

    ResultSet rst = prep.executeQuery();  

原理,SQL语句在程序运行前已经进行了预编译,在程序运行时第一次操作数据库之前,SQL语句已经被数据库分析和编译,对应的执行计划也会缓存下来,之后数据库就会以参数化的形式进行查询。

当运行时动态地把参数传给PreprareStatement时,即使参数里有敏感字符如上图中 or '1=1',它也会作为一个字段的值来处理,而不会作为一个SQL指令。

从根本上讲,其实就是data VS. code的问题,确保data永远是data,不会是可执行的code,就永远的杜绝了SQL注入这种问题。







参考博客:

http://blog.csdn.net/chenleixing/article/details/44024095

http://blog.csdn.net/daijin888888/article/details/50965232

https://www.cnblogs.com/hkncd/archive/2012/03/31/2426274.html