摘自 http://neoremind.net/2010/12/preparedstatement_diff/

JDBC中Statement與PreparedStatement的區(qū)別

1. statement每次執(zhí)行sql語(yǔ)句,相關(guān)數(shù)據(jù)庫(kù)都要執(zhí)行sql語(yǔ)句的編譯;preparedstatement是預(yù)編譯的, 采用Cache機(jī)制(預(yù)編譯語(yǔ)句,放在Cache中,下次執(zhí)行相同SQL語(yǔ)句時(shí),則可以直接從Cache中取出來(lái),有利于sql生成查詢計(jì)劃。),對(duì)于批量處理可以大大提高效率. 也叫JDBC存儲(chǔ)過(guò)程。

例如,如果要執(zhí)行兩條sql語(yǔ)句

SELECT colume FROM TABLE WHERE colume=1;
SELECT colume FROM TABLE WHERE colume=2;

會(huì)生成兩個(gè)執(zhí)行計(jì)劃

一千個(gè)查詢就生成一千個(gè)執(zhí)行計(jì)劃!

PreparedStatement用于使用綁定變量重用執(zhí)行計(jì)劃

SELECT colume FROM TABLE WHERE colume=:x;

通過(guò)set不同數(shù)據(jù)只需要生成一次執(zhí)行計(jì)劃,可以重用

是否使用綁定變量對(duì)系統(tǒng)影響非常大,生成執(zhí)行計(jì)劃極為消耗資源

兩種實(shí)現(xiàn) 速度差距可能成百上千倍

后者使用了PreparedStatement對(duì)象,而前者是普通的Statement對(duì)象。PreparedStatement對(duì)象不僅包含了SQL語(yǔ)句,而且大多數(shù)情況下這個(gè)語(yǔ)句已經(jīng)被預(yù)編譯過(guò),因而當(dāng)其執(zhí)行時(shí),只需DBMS運(yùn)行SQL語(yǔ)句,而不必先編譯。當(dāng)你需要執(zhí)行Statement對(duì)象多次的時(shí)候,PreparedStatement對(duì)象將會(huì)大大降低運(yùn)行時(shí)間,當(dāng)然也加快了訪問(wèn)數(shù)據(jù)庫(kù)的速度

這種轉(zhuǎn)換也給你帶來(lái)很大的便利,不必重復(fù)SQL語(yǔ)句的句法,而只需更改其中變量的值,便可重新執(zhí)行SQL語(yǔ)句。選擇PreparedStatement對(duì)象與否,在于相同句法的SQL語(yǔ)句是否執(zhí)行了多次,而且兩次之間的差別僅僅是變量的不同。如果僅僅執(zhí)行了一次的話,在對(duì)數(shù)據(jù)庫(kù)只執(zhí)行一次性存取的時(shí)侯,用 Statement 對(duì)象進(jìn)行處理,PreparedStatement 對(duì)象的開(kāi)銷比Statement大,對(duì)于一次性操作并不會(huì)帶來(lái)額外的好處。

2. PrepareStatement中執(zhí)行的SQL語(yǔ)句中是可以帶參數(shù)的,也就是說(shuō)可以替換變量,盡量采用使用?號(hào)的方式傳遞參數(shù),增加代碼的可讀性又可以預(yù)編譯加速;而Statement則不可以。

3. 防止SQL注入。在SQL中包含特殊字符或SQL的關(guān)鍵字(如:’ or 1 or ‘)時(shí),Statement將出現(xiàn)不可預(yù)料的結(jié)果(出現(xiàn)異常或查詢的結(jié)果不正確),可用PreparedStatement來(lái)解決。

SQL注入或者說(shuō)SQL注入攻擊就是利用Statement的漏洞完成的,例如用個(gè)用戶登錄,那么form表單有用戶名和密碼
那么我提交時(shí),在用戶名輸入框內(nèi) 輸入 “aaa’ or ’a’=’a” 密碼框隨便輸入,那么這樣意味著 sql的
查詢語(yǔ)言就是 “select * from 表 where 用戶名=’aaa’ or ’a’=’a’ and 密碼=’123’  ”,這樣查詢出來(lái)所有的數(shù)據(jù)或者是混亂。那么不被授權(quán)的用戶照樣可以登錄,豈不是被黑了?!實(shí)際中現(xiàn)在java程序員早都不用這種方式寫(xiě)查詢了,一般都用PreparedStatement來(lái)查詢,或干脆就用hibernate之類的持久層框架,這樣通過(guò)sql注入就無(wú)從談起了。