logName = (String)request.getParameter("txt_LogName");
logPwd = (String)request.getParameter("txt_LogPwd");
sql = "select useName,usePwd from userTable where useName='"+logName+"' and usePwd='"+logPwd+"'";
conn = DBConn.getConn();
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
这样的标准式代码却存在严重的安全性能。如果我们的登录界面的用户框或是密码框加入[' or '1'='1](不包括[],下同)那么上述的sql就变成了。
select useName,usePwd from userTable where useName='user ' and usePwd='test' or '1'='1'
这样的语句在Statement中是肯定成功执行的,后果是不经认证就登录了。
当然hacker从来不会这样就罢休。如果改成执行这样的,在用户框或密码框加入
[test';insert into userTable(useName,usePwd) values('hacker','123');--]
这样的话,就增加了一个永久是帐户了。
更破坏性的是[test'; drop talbe userTable;--],后果想想知道了。这也是为什么大力推荐使用PreparedStatement的主要原因。
但凡事都有度,正因为PreparedStatement是预编译的,所以在第一次执行时要比Statement慢。而且象Oracle本身就是强大的数据库优化策略,也就是说在执行Statement时,也会优化。例insert into table value('1','2'),数据库会优化成insert into table value(?,?)。这时的Statement跟PreparedStatement就是一样的了。当然有个例外,不是所有的数据库会有此优化策略。
总结一下,就是批量写记录时,绝对使用PreparedStatement,如果是多参数动态查询,一般使用Statement。当然,出于安全方面,使用PreparedStatement比较好。
【转】:http://blog.sina.com.cn/s/blog_4b65223901000d4q.html