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

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

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

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

例如,MySQL网站在下一页的“何时使用预准备语句”中提到它准备语句-MySQL

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

使用准备好的陈述,除非您有充分的理由不这样做。 准备好的语句在执行之前编译,因此可以提高性能,并提高SQL注入的安全性,因为数据库服务器负责特殊字符的编码。

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

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

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

有关更多信息: 使用预准备语句进行SQL注入?

PreparedStatements有两个主要用途:

  1. 防止SQL注入攻击。 这基本上意味着自动清理来自外部源( Web浏览器是外部的! )的输入,这些输入将被保存到数据库中。
  2. 批量处理。 如果您有大量数据要立即进入/修改/删除数据库,可以使用PreparedStatement。 在这种情况下,PreparedStatement可以优化此类操作的大部分开销,并允许您编写快速数据库批处理代码。

这两个原因都非常引人注目,几乎总是可以certificate使用PreparedStatement,但是根据你使用数据库的方式,你可能会遇到PreparedStatement不允许你做你想做的事情。

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