PreparedStatements的最佳实践;何时何时不去

时间:2010-08-02 05:14:47

标签: java mysql prepared-statement

我最近在Web应用程序中再次开始使用预准备语句,我知道不鼓励为所有事务使用预准备语句。我不知道的是什么时候最好使用准备好的陈述。

我已经阅读了何时使用而不使用它们,但没有一个例子真正说明了使用它们的最佳做法。

我试图弄清楚我应该使用哪些数据库调用以及哪些数据库调用不应该。

例如,MySQL网站在下一页Prepared Statements-MySQL

中的“何时使用预准备语句”中提及它

3 个答案:

答案 0 :(得分:6)

决定是否参加PreparedStatement的一般拇指规则是:

  

使用准备好的陈述,除非您   有足够的理由不这样做。   编制准备好的声明   在执行之前因此借给   更好的性能,并增加   作为SQL注入的安全性   数据库服务器负责   特殊字符的编码。

根据您引用的文章,我认为准备语句不如普通查询或存储过程有用的原因列表如下:

  • 一次性查询。如果您的应用程序向数据库发出单个查询,并且与其他查询相比,这种查询很少进行,则在这种情况下使用Prepared Statement可能没有意义。其基本原理是必须首先编译Prepared Statement并将语句的“编译”形式缓存以供以后使用。对于不经常运行的查询,编译是一种开销。但是,最好使用预准备语句,以避免任何SQL注入问题。
  • 数据密集型操作。有时准备语句不如存储过程有效,特别是当需要在同一事务中执行一系列操作时。当您的业务流程需要针对各种表执行多个选择,更新和删除时,存储过程通常比一堆一个接一个地执行的准备语句更好。由于为多个语句的执行进行了多次网络跳闸,因此在调用存储过程时大大减少了这种性能损失。这种效果在查询批处理中更为明显,其中在短时间内创建并销毁了多个对象。这往往是数据库管理员和应用程序开发人员之间的一个有争议的问题,因为这是一个边缘情况; DBA将相信通过SP更好地执行操作批处理,而应用程序开发人员认为PreparedStatements可以处理它(通常更好地将所有逻辑放在一个层中)。它最终归结为关于使用SP是否有利的应用程序。
  • 支持本机数据库操作和类型。。这可能不适用于MySQL,但通常JDBC标准不支持数据库支持的所有操作,以及数据库支持的所有SQL /本机/自定义类型。这在Oracle数据库(可能还有IBM DB2?)中更为明显,程序员可以创建自己的类型,这需要编写自定义Java代码,因为JDBC标准不支持数据库中的用户定义类型。类似地,数据库中的其他操作不需要支持(如MySQL文档所述) - 使用Prepared Statement无法创建用户(执行CREATE USER),修改用户权限(执行GRANT操作)等。存储过程更适合此任务,因为它们可以直接或间接方式访问数据库的本机操作集。

答案 1 :(得分:2)

为了防止SQL注入,最好在Java中使用预处理语句

有关详细信息:SQL injections with prepared statements?

答案 2 :(得分:2)

PreparedStatements有两个主要用途:

  1. 防止SQL注入攻击。这基本上意味着自动清理来自外部源( Web浏览器是外部的!)的输入,这些输入将保存到数据库中。< / LI>
  2. 批处理。如果您有大量数据要立即进入/修改/删除数据库,可以使用PreparedStatement。在这种情况下,PreparedStatement可以优化此类操作的大部分开销,并允许您编写快速数据库批处理代码。
  3. 这两个原因都是非常引人注目的理由,几乎总是可以证明使用PreparedStatement,但是根据你使用数据库的方式,你可能会遇到PreparedStatement不允许你做你想做的事情。

    作为这种情况的一个例子,我曾经编写过一个工具,它根据某些抽象的运行时属性动态生成表名,这意味着我必须能够使用可变表名进行SQL查询。你不能得到PreparedStatement那些,所以我不得不使用原始语句和一些预处理技巧来回到利用PreparedStatements进行SQL注入保护。