【问题标题】:which is faster? Statement or PreparedStatement哪个更快?语句或 PreparedStatement
【发布时间】:2012-03-21 19:54:22
【问题描述】:

通常,在网络中可以找到这样的代码:

private static final String SQL = "SELECT * FROM table_name";
....

对于这个 SQL 查询,使用 PreparedStatement。为什么?
据我所知,PreparedStatement 花时间预编译 SQL 语句。事实证明,Statement 比 PreparedStatement 更快。还是我弄错了?

【问题讨论】:

    标签: java jdbc


    【解决方案1】:

    当您必须使用不同的数据多次运行同一个语句时,准备好的语句会快得多。那是因为 SQL 只会验证一次查询,而如果你只使用一条语句,它每次都会验证查询。

    使用 PreparedStatements 的另一个好处是避免导致 SQL 注入漏洞 - 尽管在您的情况下,您的查询非常简单,您还没有遇到过。

    对于您的查询,运行准备好的语句与运行语句之间的差异可能可以忽略不计。

    编辑:针对您在下面的评论,您需要仔细查看 DAO 类以了解它在做什么。例如,如果每次调用该方法时都会重新创建准备好的语句,那么您将失去使用准备好的语句的任何好处。

    您想要实现的是对持久层的封装,这样它们就不会对 MySQL 或 Postgres 或您正在使用的任何东西进行特定调用,同时利用诸如准备好的事物的性能和安全优势陈述。为此,您需要依赖 Java 自己的对象,例如 PreparedStatement。

    我个人会构建我自己的 DAO 类来执行 CRUD 操作,在下面使用 Hibernate 和 Java Persistence API 来封装它,并且应该使用准备好的语句来获得安全优势。如果您有执行重复操作的特定用例,那么我倾向于将其包装在它自己的对象中。

    Hibernate 可以通过 XML 文件配置为使用您正在使用的任何数据库供应商,因此它提供了对持久层的非常简洁的封装。然而,它是一个相当复杂的产品!

    【讨论】:

    • 我想澄清一些事情。在我的简单 webApp 中,我有 DAO 类。在这个类中,我有使用preparedStatement的方法(通过ID获取一些信息)。多次调用该方法时,preparedStatement会预编译多少次这个SQL查询?
    • 我已经为此编辑了我的主要答案 - 这是您问题的一个有趣部分。
    • 感谢您的详细回答。 Hibernate我还没学过,不过我很快就会学的。在我的 DAO 类方法中,我重新创建了preparedStatement >.
    • @christophmccann - SQL 将验证查询。我不确定我是否理解这一点。所以 DB 不会检查通过 PreparedStatement 发出的 SQL 命令的正确性(可能除了第一个查询)?
    【解决方案2】:

    大多数时候查询并不像您的示例那么简单。如果查询有任何变化,即编译时未知的任何参数,则必须使用 PreparedStatement 以避免 SQL 注入漏洞。这胜过任何性能问题。 如果 PreparedStatement 和 Statement 之间存在任何差异,那么它将高度依赖于所讨论的特定 JDBC 驱动程序,并且大多数情况下,与访问数据库、执行实际查询和取回结果的成本相比,这种损失可以忽略不计。

    【讨论】:

    • 是的,你说的很明显。但是在这个查询中我们不需要设置任何参数,并且基于此 - 我们不会有 SQL 注入。
    • 所以,是的,正如其他人所说,如果没有参数并且只执行一次,执行 Statement 而不是 PreparedStatement 可能会稍微快一些,但我宁愿保持一致并始终使用 PreparedStatement。
    【解决方案3】:

    这里不考虑更快。 sql 的解析通常只是整体执行的一小部分。更多信息请访问When should we use a PreparedStatement instead of a Statement?

    【讨论】:

      【解决方案4】:

      据我所知,PreparedStatement 比声明快得多。这里是preparedstatement 比statement 更快的一些原因,请阅读更多详细信息。
      JDBC API 提供了与数据库连接的功能。然后我们尝试使用语句和preparedstatement执行查询。
      执行查询有四个步骤。

      解析sql查询。
      编译此查询。
      优化数据采集路径。
      执行查询。

      语句接口适用于我们不需要多次执行查询的情况。

      语句接口的缺点。 黑客可以轻松破解数据。就像假设我们有一个查询,其中用户名和密码是一个参数,您可以提供正确的参数是 username='abc@example.com' 和 password ='abc123' 实际上这是当前但黑客可以做 username='abc@ example.com' 或 '1'=1 和 password='' 表示您可以成功登录。所以这在 Statement 中是可能发生的。
      每次我们从数据库中获取数据时,都会进行 sql 验证。

      所以 Java 有针对上述问题的解决方案,即 PreparedStatement。 这个接口有很多优点。 preparedstatement 的主要优点是 sql 不是每次都验证查询。所以你可以快速得到结果。请阅读以下preparedstatement的更多优点。

      1) 我们可以安全地使用 setter 方法提供查询参数的值。 2)它可以防止SQL注入,因为它会自动转义特殊字符。 3)当我们使用上面的语句时,每次都会执行四个步骤但是当我们使用 PreparedStatement 时,只执行最后一步,所以这比语句更快。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-29
        • 1970-01-01
        • 1970-01-01
        • 2015-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-10
        相关资源
        最近更新 更多