Java 哪个更快?陈述或准备陈述

Java 哪个更快?陈述或准备陈述,java,jdbc,Java,Jdbc,通常,在网络中可以找到如下代码: private static final String SQL = "SELECT * FROM table_name"; .... 对于此SQL查询,使用PreparedStatement。为什么? 据我所知,PreparedStatement花时间预编译SQL语句。事实证明,该语句比PreparedStatement快。或者我弄错了?大多数情况下,查询并不像您的示例那样简单。如果查询有任何变化,即编译时未知的任何参数,则必须使用PreparedStatem

通常,在网络中可以找到如下代码:

private static final String SQL = "SELECT * FROM table_name";
....
对于此SQL查询,使用PreparedStatement。为什么?

据我所知,PreparedStatement花时间预编译SQL语句。事实证明,该语句比PreparedStatement快。或者我弄错了?

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

这里不考虑更快。sql的解析通常只是整个执行的一小部分。更多信息请参见

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

使用PreparedStatements的另一个好处是避免造成SQL注入漏洞——尽管在您的情况下,您的查询非常简单,您还没有遇到过这样的问题

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

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

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

我个人会构建自己的DAO类来执行CRUD操作,在下面使用Hibernate和Java持久性API来封装所有内容,为了安全起见,应该使用准备好的语句。如果您有执行重复操作的特定用例,那么我倾向于将其封装在自己的对象中


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

据我所知,准备好的陈述比陈述快得多。以下是preparedstatement比statement快的一些原因,请阅读以了解更多详细信息。
JDBCAPI提供了与数据库连接的功能。然后我们尝试使用statement和preparedstatement执行查询。
执行查询有四个步骤

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

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

语句接口的缺点。 黑客可以轻易地破解数据。假设我们有一个查询,其中用户名和密码是一个参数,您可以给正确的参数是username=abc@example.com'和password='abc123'实际上这是最新的,但黑客可以使用用户名='abc123'abc@example.com'或'1'=1,密码='',这意味着您可以成功登录。所以这在声明中是可能发生的。
每次从数据库中获取数据时,sql都会进行验证

因此,Java为上述问题提供了解决方案,即PreparedStatement。 这个接口有很多优点。preparedstatement的主要优点是sql不会每次都验证查询。所以你可以很快得到结果。请阅读下面的“准备声明”的更多优点

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

是的,你说的是显而易见的事情。但是在这个查询中,我们不需要设置任何参数,基于此,我们将不使用SQL注入。所以,是的,正如其他人所说,如果没有参数,并且只执行一次,那么执行语句而不是PreparedStatement可能会稍微快一点,但我宁愿保持一致,总是使用事先准备好的声明。我想澄清一些事情。在我的简单webApp中,我有DAO类。在这个类中,我有一个使用preparedStatement的方法(通过ID获取一些信息)。多次调用此方法时,preparedStatement将预编译此SQL查询多少次?我已编辑了主要答案-这是您问题的一个有趣部分。感谢您提供的详细答案。冬眠我还没有学习,但我很快就会学会。在我的DAO类方法中,我重新创建了preparedStatement>@christophmccann-SQL将验证查询。我不确定我是否理解这一点。所以DB不会检查通过PreparedStatement发出的SQL命令的正确性(第一次查询除外)?