2011-01-10 58 views
6

我們都是knowthat我們應該重用JDBC PreparedStatement而不是在循環中創建一個新的實例。如何處理PreparedStatement不同的方法調用之間的重用? 重用 - 「規則」是否仍然計數?在方法之間重用PreparedStatement?

我真的應該考慮使用PreparedStatement的字段,還是應該在每次調用時關閉並重新創建準備語句(保持本地狀態)? (當然這樣的類的實例將被綁定到Connection,這在某些體系結構中可能是缺點)

我知道理想的答案可能是「取決於」。
但是我正在尋找一個經驗較少的開發者的最佳實踐,他們會在大多數情況下做出正確的選擇。

+3

絕對不要讓它成爲這個類的領域。保持本地化。 – BalusC 2011-01-10 13:59:39

回答

13

當然,這樣的類的實例將被綁定到這可能是一個缺點

可能是有關聯嗎?這將是一個巨大的的劣勢。你需要同步對它的訪問,這會殺死你的多用戶性能,或者創建多個實例並將它們保存在一個池中。在屁股的主要痛苦。

語句池是JDBC驅動程序的工作,並且大多數(如果不是全部的話)當前作物驅動程序會爲您執行此操作。當您撥打prepareStatementprepareCall時,驅動程序將處理重新使用現有資源和預編譯語句。

Statement對象綁定到一個連接,應該儘可能快地使用連接並返回到池中。

總之,在方法的開始獲得PreparedStatement,反覆使用它的環路內,則在該方法的結束時關閉它的標準做法,最佳實踐。

+0

我不明白爲什麼這是一個大問題。每個連接有一個線程。每個服務類(包含您的CRUD方法)預先構建PreparedStatements,並在所有方法中重用它們。當連接關閉時,PreparedStatements會關閉。 – Gili 2011-01-19 00:53:00

0

是的,它可以重複使用,但我相信這隻有在使用相同的Connection對象並且您正在使用數據庫連接池(例如來自Web應用程序內部)時纔會計數,那麼Connection對象將有可能每次都不一樣。

因爲這個原因,在Web應用程序中每次使用之前我總是重新創建PreparedStatement

如果你不使用連接池,那麼你是金!

0

我沒有看到區別:如果我對同一個連接重複執行相同的語句,爲什麼不以任何方式重用PreparedStatement?如果多個方法執行相同的語句,那麼可能該語句需要封裝在自己的方法(甚至是它自己的類)中。這樣你就不需要傳遞一個PreparedStatement

+1

由於PreparedStatement「屬於」特定的連接,因此您不能在不同的連接中重複使用它。當然,您可以重用一些將在不同連接中執行的代碼,但關於PreparedStatment的好處是隻需將其準備好一次並重新使用即可,一旦您使用不同的Connection,這是不可能的。 – 2013-12-12 10:29:36

6

許多數據庫工作負載受CPU限制,而不受IO限制。這意味着數據庫最終會花費更多的時間進行工作,比如解析SQL查詢並計算如何處理它們(執行'執行計劃'),而不是花費在訪問磁盤上。對於「事務性」工作負載而言,這比「報告」工作負載更爲真實,但在這兩種情況下,準備計劃的時間可能超出您的預期。

因此,如果語句要經常執行,並且在方法調用之間緩存PreparedStatements的「正確」安排的麻煩值得您的開發人員時間,那麼這總是一個好主意。與性能一樣,衡量是關鍵,但如果您可以做到便宜,可以將PreparedStatement緩存在習慣之外。

某些JDBC驅動程序和/或連接池提供了透明的「準備好的語句緩存」,因此您不必親自去做。只要您瞭解您選擇的特定透明緩存策略的行爲,就可以讓它跟蹤事情,這是很好的事情......您真正想要避免的是數據庫上的命中。

+0

有很多理智的查詢需要在數據庫上提供大量的IO。具體而言,任何對大型數據集進行計算/聚合/ ...的任何事情。 – 2011-01-10 14:05:29