百度上首先查资料得到如下:


SQL注入***是利用设计上的漏洞,在目标服务器上运行SQL语句进行***,动态生成SQL语句时没有对用户输入的数据进行验证是SQL注入*** 得逞的主要 原因.
对于JDBC而言,SQL注入***只对Statement有效,对PreparedStatement是无效的,这是因为PreparedStatement不允许在插入时改变查询的逻辑结构.
绕过验证,但这 种手段只对Statement有效,对PreparedStatement无效.

如果有一条SQL语句: "select* from 表 where 用户名 = '用户名'"
Statement的SQL语句是这样写的: "select * from 表 where 用户名 = '"+ 变量值 +"'"
PreparedStatement的SQL语句是这样写的: "select * from 表 where 用户名 = ?" 然后对应?赋值
这样我们就发现输入 "aa' or '1' = '1"
Statement是将这个和SQL语句做字符串连接到一起执行
PreparedStatement是将 "aa' or '1' = '1" 作为一个字符串赋值给?,做为"用户名"字段的对应值,显然这样SQL注入无从谈起了

重点在下面几句话:

实现机制不同,注入只对SQL语句的准备(编译)过程有破坏作用,而PreparedStatement已经准备好了,执行阶段只是把输入串作为数据处理,不再需要对SQL语句进行解析,准备,因此也就避免了SQL注入问题.  

关键点: PreparedStatement 之所以避免了SQL注入。是因为 对输入的字符串 不会再进行编译解析了。。而是直接拿去执行了。。。SQL注入就是利用的SQL的解析时对字符串中的特殊符号 解析 产生了偏差。诱使 一条唯一性的SQL查询语句变成了多重语义的查询语句了。(或查询 or  \  联合查询 UNION 咯) 从而使不法分子钻了空子。。