PreparedStatement能防止sql注入的原理

Class.forName(com.mysql.jdbc.Driver);
Connection con = DriverManager.getConnection("jdbc:mysql://....");
Statement st = con.CreateStatement();
String id = "03";
String sq = "delete from table1 where id="+id;
st.execute(sq);

上面这段代码的本意是要删除id=03的记录,但是如果有人将id的内容改为“03 or 1=1”。 那么表中的任何记录都将被删除,后果十分严重。 而且登录界面用户可以在输入的时候加上两个冒号作为特殊字符, 这样的话会让计算机认为他输入的是SQL语句的关键字从而改变你的SQL语句, 造成不可估量的损失。 这是Statement的一大缺点:不能防止sql注入。 另一个缺点是,每次执行都需要重新编译sql语句,效率低下。 而PreparedStatement则解决了这些问题。

为什么PreparedStatement能防止sql注入呢? 因为sql语句是预编译的,而且语句中使用了占位符,规定了sql语句的结构。 用户可以设置"?"的值,但是不能改变sql语句的结构, 因此想在sql语句后面加上如“or 1=1”(1=1能查出全部用户)等奇怪字符串的拼接来实现sql注入是行不通的。 实际开发中,一般采用PreparedStatement访问数据库,它不仅能防止sql注入, 还是预编译的(不用改变一次参数就要重新编译整个sql语句,效率高), 此外,它执行查询语句得到的结果集是离线的,连接关闭后,仍然可以访问结果集。

经验分享 程序员 微信小程序 职场和发展