在使用Java将数据插入数据库之前,推荐使用哪种方法来转义变量?
据我所知,我可以使用PreparedStatement.setString()来转义数据,但是如果我不打算再次运行相同的查询,那么PreparedStatement似乎有点不切实际。有没有更好的方法来做它而不准备每个查询?
答案 0 :(得分:27)
是的,使用预先准备好的陈述。
他们被解析了一次。
他们免受SQL注入攻击。
他们是一个更好的设计,因为你必须考虑你的SQL及其使用方式。
如果你认为他们只使用过一次,你就不会看大局。有一天,您的数据或应用程序将发生变化。
修改强>
为什么准备好的语句会让你考虑你的SQL?
组装字符串(或只是执行文字文本块)时,您不会创建新的PreparedStatement
对象。你只是在执行SQL - 它可以非常随意地完成。
当您必须创建(并保存)PreparedStatement
时,您必须更多地考虑封装,责任分配。在进行任何SQL处理之前,语句的准备是一个有状态事件。
额外的工作很小,但并非无足轻重。这是导致人们开始考虑ORM和数据缓存层的原因,以及类似的东西来优化他们的数据库访问。
使用Prepared语句,数据库访问不那么随意,更有意。
答案 1 :(得分:9)
您永远不应该使用字符串连接自己构造SQL查询。在构造SQL查询时,不应手动转义变量/用户数据。所需的实际转义取决于您的基础数据库,并且在某些时候有人会忘记逃避。
重点在于:使用预准备语句,不可能创建SQL注入语句。通过自定义转义,这是可能的。选择很明显。
答案 2 :(得分:4)
准备一份声明并不昂贵。它比大多数替代品更安全。
答案 3 :(得分:3)
我听说过,PreparedStatement比普通的Statement花费了一些额外的开销,如果我没有将用户输入连接到我的查询中,它应该是安全的。这可能是真的,但额外的成本并不是那么多,SQL查询会随着时间而变化。如果您今天开始使用Statement,因为您已经证明您的查询是注入防范的,那么您在维护程序员更改SQL以接受用户输入的那一天就会失败,但是没有我想将该声明更改为PreparedStatement。我的建议是始终使用PreparedStatement在发现问题之前解决问题。
答案 4 :(得分:3)
更好的是,不要直接使用JDBC API,因为它非常容易出错(例如,在所有情况下都无法正确清理所有资源)。使用JDBC帮助程序对象,例如Spring的JdbcOperations接口,这大大减少了代码的大小和繁琐。如果您只使用Spring来实现这一功能,那么与直接使用JDBC API相比,您仍然可以获得巨大的帮助。