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语句,效率高),
此外,它执行查询语句得到的结果集是离线的,连接关闭后,仍然可以访问结果集。