哪个更快?Statement 还是 PreparedStatement?

8
经常在网络上可以找到这样的代码:
private static final String SQL = "SELECT * FROM table_name";
....

为了执行这个SQL查询,需要使用PreparedStatement。为什么呢?
据我所知,PreparedStatement需要花费时间来预编译SQL语句。但事实证明,Statement比PreparedStatement更快。或者我理解错了吗?


这个回答解决了你的问题吗?PreparedStatements 和性能 - rogerdpack
4个回答

16

当需要多次运行相同语句但数据不同时,使用预编译语句可以极大提升速度。这是因为SQL仅会验证查询一次,而如果您只使用语句,则每次都要验证查询。

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

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

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

您想要实现的是封装持久层,使其无需特定调用MySQL或Postgres或您正在使用的其他数据库,并同时利用准备好的语句等性能和安全性优势。为此,您需要依赖Java自身的对象,如PreparedStatement。

我个人会构建自己的DAO类来执行CRUD操作,使用Hibernate作为基础框架和Java Persistence API来封装它,这样就可以利用准备好的语句获得安全性的好处。如果您有针对重复操作的特定用例,那么我倾向于将其包装在自己的对象中。

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


我想澄清一些事情。在我的简单Web应用程序中,我有DAO类。在这个类中,我有一个方法(通过ID获取一些信息),它使用了preparedStatement。当多次调用此方法时,preparedStatement会预编译SQL查询语句多少次? - Ifozest
我已经编辑了我的主要回答——这是你问题中有趣的部分。 - christophmccann
谢谢你详细的回答。Hibernate我还没有学过,但我很快就会学习。在我的DAO类方法中,我重新创建了preparedStatement >.< - Ifozest
@christophmccann - SQL会验证查询。我不确定我是否理解了这一点。所以,DB不会检查通过PreparedStatement发出的SQL命令的正确性(除了第一个查询可能)吗? - david blaine

4

大多数情况下,查询并不像你的示例那样简单。如果有任何查询变化,例如任何参数在编译时间未知,则必须使用PreparedStatement以避免SQL注入漏洞。这比任何性能考虑都更重要。 如果PreparedStatement和Statement之间有任何区别,那将高度依赖于具体的JDBC驱动程序,并且大多数时候惩罚与访问数据库、执行实际查询和获取结果的成本相比微不足道。


是的,你说的很明显。但在这个查询中,我们不需要设置任何参数,基于此 - 我们将不会有SQL注入问题。 - Ifozest
1
是的,正如其他人所说,如果没有参数并且只执行一次,使用Statement可能会稍微快一些,但我宁愿保持一致并始终使用PreparedStatement。 - MK.

1
根据我的了解,PreparedStatement比Statement更快。以下是PreparedStatement比Statement更快的一些原因,请阅读获取更多详细信息。
提供了与数据库连接的功能。然后我们尝试使用Statement和PreparedStatement执行查询。
有四个步骤来执行查询。

解析SQL查询。
编译此查询。
优化数据获取路径。
执行查询。

当我们不需要多次执行查询时,Statement接口是适合的。 Statement接口的缺点。黑客可以轻松地窃取数据。例如,假设我们有一个查询,其中用户名和密码是参数,您可以为用户名='abc@example.com'和密码='abc123'提供正确的参数,实际上这是当前的情况。但黑客可以做到用户名='abc@example.com'或'1'=1和密码='',这意味着您可以成功登录。所以这在Statement中是可能发生的。
每次从数据库获取数据时都要进行SQL验证。
所以Java有解决上述问题的方案,那就是PreparedStatement。这个接口有很多优点,其中主要的优点是sql不需要每次验证查询,因此可以更快地得到结果。请阅读下面更多有关PreparedStatement的优点。
1)我们可以安全地使用setter方法提供查询参数的值。 2)它可以防止SQL注入,因为它会自动转义特殊字符。 3)当我们使用语句时,每次都要执行以上四个步骤,但当我们使用PreparedStatement时,只需执行最后一个步骤,因此比语句更快。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接