我正在做一个分配广告有一个更新类,它接受了sql和更新的表。我正在使用Java。我是这样做的
sqls = "INSERT INTO statistics(ID, TeamName, Wins, Draws, Losses, Points, DatePlayed) VALUES ( 0 ,'"+var1+"',"+var2+","+var3+","+var4+","+var5+",'"+ date +"')";
Class.forName("com.mysql.jdbc.Driver").newInstance();
con = DriverManager.getConnection("jdbc:mysql://localhost/players","root", "123");
stmt = con.prepareStatement(sqls);
int updaterows = stmt.executeUpdate(sqls);
我的老师这样做了
sqls = "INSERT INTO statistics(TeamName, Wins, Draws, Losses, Points, DatePlayed) VALUES ( ?,?,?,?,?,?)"
Class.forName("com.mysql.jdbc.Driver").newInstance();
con = DriverManager.getConnection("jdbc:mysql://localhost/players","root", "123");
stmt = con.prepareStatement(sqls);
stmt.setString(1, var1);
stmt.setInt(2, var2);
stmt.setInt(3, var3);
stmt.setInt(4, var4);
stmt.setInt(5, var5);
stmt.setTimestamp(6, var6);
int updaterows = stmt.executeUpdate();
哪一个更好,为什么请它让我感到困惑,因为这两种方法都有效。
答案 0 :(得分:8)
绝对使用第二种方式 - 老师的方式。你的方式非常危险,因为代码很容易sql injection。任何人都可以DROP DATABASE
作为TeamName
输入您的数据库。
P.S有些有趣 - Bobby Tables。
答案 1 :(得分:4)
老师的方式更好,因为它可以阻止sql injection攻击。
答案 2 :(得分:2)
第二种方式在很多方面都更好(老师的方式):
安全性:
它可以防止sql注入攻击。 参考:https://www.owasp.org/index.php/Preventing_SQL_Injection_in_Java
可扩展性:
它可以防止重复字符串连接导致过多的内存使用。 参考:http://docs.oracle.com/cd/E18930_01/html/821-2431/abebf.html#abebh
性能:
它允许数据库创建预准备语句(预编译的sql查询)。 参考:http://docs.oracle.com/javase/1.4.2/docs/api/java/sql/PreparedStatement.html
可维护性:
它允许在编译时对sql参数进行类型检查。
答案 3 :(得分:1)
两种方式都可以完成工作,第二种方式更好,因为它更安全并且可以防止sql注入。但我想指出每个人都跳过的一件事,使用预准备语句,PreparedStatement调用是预编译的,并提供更好的性能。
如果在会话中多次使用某个语句,则预编译它会比将其发送到数据库并为每次使用编译它提供更好的性能。声明越复杂,性能优势就越大。 如果语句可能只使用了几次,那么预编译它可能效率低,因为预编译,保存以及稍后在数据库中释放它所涉及的开销。
另外,我建议您检查CallableStatement,您可以创建一个存储过程并将SQL查询放入其中并使用CallableStatement运行存储过程。 Callable Statement提供了更好的性能,因为它完全在数据库上运行(如果你有一个远程数据库,你的网络很慢,你会注意到性能)以及更好的安全性。
答案 4 :(得分:0)
第二个版本使用查询参数,从SQL注入的角度来看更安全。有关详细信息,请参阅Google SQL注入。