我是否应该将PreparedStatements用于Java中的所有数据库插入?

时间:2008-12-28 22:11:23

标签: java mysql connection prepared-statement

在使用Java将数据插入数据库之前,推荐使用哪种方法来转义变量?

据我所知,我可以使用PreparedStatement.setString()来转义数据,但是如果我不打算再次运行相同的查询,那么PreparedStatement似乎有点不切实际。有没有更好的方法来做它而不准备每个查询?

5 个答案:

答案 0 :(得分:27)

是的,使用预先准备好的陈述。

  1. 他们被解析了一次。

  2. 他们免受SQL注入攻击。

  3. 他们是一个更好的设计,因为你必须考虑你的SQL及其使用方式。

  4. 如果你认为他们只使用过一次,你就不会看大局。有一天,您的数据或应用程序将发生变化。


    修改

    为什么准备好的语句会让你考虑你的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相比,您仍然可以获得巨大的帮助。