2012-03-03 157 views
6

通常情況下,在網絡中可以發現這樣的代碼:哪個更快? Statement或PreparedStatement

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

,併爲這個SQL查詢中使用PreparedStatement的。爲什麼?
據我所知,PreparedStatement花時間預編譯SQL語句。事實證明,這樣Statement比PreparedStatement更快。或者我錯了?

回答

11

當您不得不多次運行相同的語句並使用不同的數據時,準備好的語句要快得多。那是因爲SQL只會驗證一次查詢,而如果你只是使用一條語句,它會每次驗證查詢。

使用PreparedStatements的其他好處是避免造成SQL注入漏洞 - 儘管在您的情況下您的查詢非常簡單,您還沒有遇到過。

對於您的查詢,運行預處理語句與語句之間的區別可能可以忽略不計。

編輯:在迴應您的評論下面,你需要仔細看看DAO類,看看它在做什麼。例如,如果每次調用該方法時重新創建預準備語句,那麼您將失去使用預準備語句的好處。

你想要實現的是持久層的封裝,以便它們沒有特定的調用MySQL或Postgres或者你正在使用的任何東西,並且同時利用類似事件的性能和安全性好處準備好的陳述爲此,您需要依賴Java自己的對象,如PreparedStatement。

我個人會建立我自己的DAO類來做CRUD操作,使用下面的Hibernate和Java Persistence API來封裝它,並且應該使用預先準備好的語句來提高安全性。如果你有重複操作的特定用例,那麼我會傾向於將它包裝在它自己的對象中。

可以將Hibernate配置爲通過XML文件使用您正在使用的任何數據庫供應商,因此它提供了對持久層的真正封裝。但是,獲得正確的產品是相當複雜的產品!

+0

我想澄清一些事情。在我簡單的webApp我有DAO類。在這個類中,我有使用preparedStatement的方法(通過ID獲取一些信息)。當多次調用這個方法時,prepareStatement會預編譯這個SQL查詢多少次? – Ifozest 2012-03-04 18:41:32

+0

我編輯了我的主要答案 - 這是你問題中有趣的部分。 – christophmccann 2012-03-04 18:44:36

+1

請參閱編輯現在瞭解更多信息。 – christophmccann 2012-03-04 18:58:16

4

大多數時間查詢並不像您的示例那麼簡單。如果查詢有任何變化,即編譯時未知的任何參數,則必須使用PreparedStatement來避免SQL注入漏洞。這勝過任何性能問題。 如果PreparedStatement和Statement之間有任何區別,它將高度依賴於特定的JDBC驅動程序,並且大多數情況下,與進入數據庫,執行實際查詢和獲取結果的成本相比,懲罰可以忽略不計。

+0

是的,你說的是明顯的事情。但在這個查詢中,我們不需要設置任何參數,並基於此 - 我們不會有SQL注入。 – Ifozest 2012-03-03 17:32:43

+1

所以是的,正如其他人所說,如果沒有參數並且只執行一次,那麼執行Statement而不是PreparedStatement可能會稍微快一點,但我寧願保持一致並始終使用PreparedStatement。 – 2012-03-03 17:37:20

0

由於根據我的知識PreparedStatement比聲明要快得多。這裏有一些原因,爲什麼預備陳述更快然後陳述請閱讀更多的細節。
JDBC API提供了與數據庫連接的功能。然後我們嘗試使用語句和準備語句來執行查詢。
執行查詢有四個步驟。

解析sql查詢。
編譯此查詢。
數據採集路徑的優化。
執行查詢。

聲明接口適用於我們不需要多次執行查詢的情況。

Statement接口的缺點。 黑客可以輕易破解數據。就像我們有一個查詢,其中有用戶名和密碼是一個參數,你可以給出正確的參數是username='[email protected]'和密碼='abc123'實際上這是當前但黑客可以做username ='abc @ example.com'或'1'= 1和密碼='',這意味着您可以成功登錄。這在聲明中可能發生。
每當我們從數據庫中獲取數據時,sql都會驗證。

因此,Java有解決上述問題的方法是PreparedStatement。 這個接口有很多優點。 preparedstatement的主要優點是sql不是每次都驗證查詢。所以你可以快速得到結果。請閱讀以下更多的準備陳述的優點。

1)我們可以安全地使用setter方法提供查詢參數的值。 2)它防止SQL注入,因爲它會自動轉義特殊字符。 3)當我們使用上面的語句時,每次都執行四個步驟但是當我們使用PreparedStatement時,只執行最後一個步驟,所以這比語句更快。