JDBC中Statement與PreparedStatement的區別
1. statement每次執行sql語句,相關數據庫都要執行sql語句的編譯;preparedstatement是預編譯的, 采用Cache機制(預編譯語句,放在Cache中,下次執行相同SQL語句時,則可以直接從Cache中取出來,有利於sql生成查詢計劃。),對於批量處理可以大大提高效率. 也叫JDBC存儲過程。
例如,如果要執行兩條sql語句
SELECT colume FROM TABLE WHERE colume=1;
SELECT colume FROM TABLE WHERE colume=2;
會生成兩個執行計劃
一千個查詢就生成一千個執行計劃!
PreparedStatement用於使用綁定變量重用執行計劃
SELECT colume FROM TABLE WHERE colume=:x;
通過set不同數據只需要生成一次執行計劃,可以重用
是否使用綁定變量對系統影響非常大,生成執行計劃極為消耗資源
兩種實現 速度差距可能成百上千倍
後者使用了PreparedStatement對象,而前者是普通的Statement對象。PreparedStatement對象不僅包含了SQL語句,而且大多數情況下這個語句已經被預編譯過,因而當其執行時,只需DBMS運行SQL語句,而不必先編譯。當你需要執行Statement對象多次的時候,PreparedStatement對象將會大大降低運行時間,當然也加快了訪問數據庫的速度
這種轉換也給你帶來很大的便利,不必重復SQL語句的句法,而只需更改其中變量的值,便可重新執行SQL語句。選擇PreparedStatement對象與否,在於相同句法的SQL語句是否執行了多次,而且兩次之間的差別僅僅是變量的不同。如果僅僅執行了一次的話,在對數據庫只執行一次性存取的時侯,用 Statement 對象進行處理,PreparedStatement 對象的開銷比Statement大,對於一次性操作並不會帶來額外的好處。
2. PrepareStatement中執行的SQL語句中是可以帶參數的,也就是說可以替換變量,盡量采用使用?號的方式傳遞參數,增加代碼的可讀性又可以預編譯加速;而Statement則不可以。
3. 防止SQL註入。在SQL中包含特殊字符或SQL的關鍵字(如:’ or 1 or ‘)時,Statement將出現不可預料的結果(出現異常或查詢的結果不正確),可用PreparedStatement來解決。
SQL註入或者說SQL註入攻擊就是利用Statement的漏洞完成的,例如用個用戶登錄,那麽form表單有用戶名和密碼 那麽我提交時,在用戶名輸入框內 輸入 “aaa’ or ’a’=’a” 密碼框隨便輸入,那麽這樣意味著 sql的 查詢語言就是 “select * from 表 where 用戶名=’aaa’ or ’a’=’a’ and 密碼=’123’ ”,這樣查詢出來所有的數據或者是混亂。那麽不被授權的用戶照樣可以登錄,豈不是被黑了?!實際中現在java程序員早都不用這種方式寫查詢了,一般都用PreparedStatement來查詢,或幹脆就用hibernate之類的持久層框架,這樣通過sql註入就無從談起了。JDBC中Statement與PreparedStatement的區別