< 1000; ++I) { PreparedStatement ps = conn.prepareStatement("select a,b from t where c = " + I); ResultSet rs = Ps.executeQuery(); Rs.close(); Ps.close(); } 這里不會用到緩沖. 每次循環向數據庫發送一條不同的 SQL 語句. 每次循環都重新計算新的訪問 方案, 用這種方法我們會浪費大量的 CPU 周期. 但是, 看看下一個片段: PreparedStatement ps = conn.prepareStatement("select a,b from t where c = ?"); For(int I = 0; I < 1000; ++I) { ps.setInt(1, I); ResultSet rs = ps.executeQuery(); Rs.close(); } ps.close(); 這樣就會高效得多. 發送給數據庫的語句在 sql 中使用 @#?@# 符號來參數化. 這意味著每次循環 發送是同一條語句, 在 "c=?" 部分帶有不同的參數. 這樣就允許數據庫重用語句的訪問方案, 是程序在數據庫內部運行得更高效. 這基本上能使你的程序 運行得更快, 或者使數據庫用戶能更多 地使用 CPU. PreparedStatement 和 J2EE 服務器當我們使用 J2EE 服務器的時候, 事情會變得更加復雜. 通常情況下, 一個預先準備好的語句 (prepared statement) 是和一個單獨的數據庫連接相關聯的. 當連接關閉時, 語句就被丟棄 了. 一般來說, 一個胖客戶端應用程序在得到一個數據庫連接后會一 直保持到程序結束. 它會使用 兩種方法創建所有的語句: 急切創建(eagerly) 或者 懶惰創建(lazily). Eagerly是說, 當程序啟動時全部創建. Lazily是說隨用隨創建. 急切的方法會在程序啟動時有些延時, 但是一旦程序啟動以后, 運行很好. 懶惰的方法啟動很快, 但是當程序運行時, 預先準備的語句在第一次使用是創建. 這就會造成性能 不平衡, 知道所有的 語句都準備好了, 但是最終程序會和急切方法一樣快. 哪一種最好要看你需要的是快速啟動還是 均衡的性能. 一個 J2EE 應用程序所帶來的問題就是它不能像這樣工作. 它只在一個請求的生存時間中保持一個 連接. 這意味著在他處理每一個請求時都會重新創建語句, 就不象胖客戶端只創建一次, 而不是每 個請求都創建那樣有效, 當 J2EE 服務器給你的程序一個連接時, 并不是一個真正的連接, 而是一個經過包裝的. 你可以通過查看那個連接的類的名字來檢驗一下. 它不是一個數據庫的 JDBC 連接, 是你的服務器創建 的一個類. 通常, 如果你調用一個連接的 close 方法, 那么 jdbc 驅動程序會關閉這個連接. 我們希望的是當 J2EE 應用程序調用 close 的時候, 連接會返回到連接池中. 我們通過設計一個 代理的 jdbc 連接類來做這些, 但看起來 就象是實際的連接. 當我們調用這個連接的任何方法時, 代理類就會把請求前遞給 實際的連接. 但是, 當我們調用類似 close 的方法時, 并不調用實際 連接的 close 方法, 只是簡單地把連接返回給連接池, 然后把代理連接標記為無效, 這樣當它 被應用程序重新使用時, 我們會得到異常.包裝是非常有用的, 因為它幫助J2EE 應用程序服務器實現者比較聰明地加上預先準備語句的 支持. 當程序調用Connection.prepareStatement 時, 由驅動程序返回一 個 PreparedStatement 對象. 當應用程序得到它時, 保存這個句柄, 并且在請求完成時, 關閉 請求之前關閉這個句柄. 但是, 在連接返回到連接池之后, 以后被同樣或者 另一個應用程序重用時, 那么, 我們就理論上希望同樣的 PreparedStatement 返回給 應用程序.
猜你喜歡
- 晚上涂了a醇早上要洗臉嗎?
- 校運動會班級簡介
- 建構筑物消防員證幾年一審?
- 定期存單掛失多久可取
- tbc平臺是什么意思
- 摩托車交強險可以重復購買嗎?
- 泥石流是怎么形成的
- 手機屏幕密碼在哪里設置
- 蟹味菇是什么
- 重陽節的手抄報圖片
