JDBC中Statement與PreparedStatement的區(qū)別
1. statement每次執(zhí)行sql語句,相關(guān)數(shù)據(jù)庫都要執(zhí)行sql語句的編譯;preparedstatement是預(yù)編譯的, 采用Cache機(jī)制(預(yù)編譯語句,放在Cache中,下次執(zhí)行相同SQL語句時(shí),則可以直接從Cache中取出來,有利于sql生成查詢計(jì)劃。),對(duì)于批量處理可以大大提高效率. 也叫JDBC存儲(chǔ)過程。
例如,如果要執(zhí)行兩條sql語句
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;
通過set不同數(shù)據(jù)只需要生成一次執(zhí)行計(jì)劃,可以重用
是否使用綁定變量對(duì)系統(tǒng)影響非常大,生成執(zhí)行計(jì)劃極為消耗資源
兩種實(shí)現(xiàn) 速度差距可能成百上千倍
后者使用了PreparedStatement對(duì)象,而前者是普通的Statement對(duì)象。PreparedStatement對(duì)象不僅包含了SQL語句,而且大多數(shù)情況下這個(gè)語句已經(jīng)被預(yù)編譯過,因而當(dāng)其執(zhí)行時(shí),只需DBMS運(yùn)行SQL語句,而不必先編譯。當(dāng)你需要執(zhí)行Statement對(duì)象多次的時(shí)候,PreparedStatement對(duì)象將會(huì)大大降低運(yùn)行時(shí)間,當(dāng)然也加快了訪問數(shù)據(jù)庫的速度。
這種轉(zhuǎn)換也給你帶來很大的便利,不必重復(fù)SQL語句的句法,而只需更改其中變量的值,便可重新執(zhí)行SQL語句。選擇PreparedStatement對(duì)象與否,在于相同句法的SQL語句是否執(zhí)行了多次,而且兩次之間的差別僅僅是變量的不同。如果僅僅執(zhí)行了一次的話,在對(duì)數(shù)據(jù)庫只執(zhí)行一次性存取的時(shí)侯,用 Statement 對(duì)象進(jìn)行處理,PreparedStatement 對(duì)象的開銷比Statement大,對(duì)于一次性操作并不會(huì)帶來額外的好處。
2. PrepareStatement中執(zhí)行的SQL語句中是可以帶參數(shù)的,也就是說可以替換變量,盡量采用使用?號(hào)的方式傳遞參數(shù),增加代碼的可讀性又可以預(yù)編譯加速;而Statement則不可以。
3. 防止SQL注入。在SQL中包含特殊字符或SQL的關(guān)鍵字(如:’ or 1 or ‘)時(shí),Statement將出現(xiàn)不可預(yù)料的結(jié)果(出現(xiàn)異常或查詢的結(jié)果不正確),可用PreparedStatement來解決。