一直都不是蠻清楚這兩者的區別聯繫,今天就開一貼來詳細的分析一下主要是從可讀性,性能和效率上面來加以分析
html
在可讀性方面來講:
java
//Statement編寫語句方法: stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')"); //PreparedStatement: pstmt = con.prepareStatement("insert into tb_name(col1,col2,col2,col4) values (?,?,?,?)"); pstmt.setString(1,var1); pstmt.setString(2,var2); pstmt.setString(3,var3); pstmt.setString(4,var4); pstmt.executeUpdate();
statement 顯得比較亂並且由於引號的緣由比較容易出錯,而preparedment則比較直觀簡潔mysql
2.在性能方面:
sql
每種數據庫都會對預編譯的語句提供最大的性能優化,由於有些編譯語句會被重複調用,因此就把被數據庫編譯後的執行代碼緩存起來,當下次調用只要是相同的預編譯語句就不須要編譯,只要將參數傳入預編譯的語句執行代碼(至關於一個函數)中就會獲得執行,所以大大提升了效率(對mysql來講沒有多大區別可是對Oracle來講差距就很是明顯)數據庫
其次是Batch的使用
緩存
//屢次執行preparestatement PreparedStatement ps = conn.prepareStatement( "INSERT into employees values (?, ?, ?)"); for (n = 0; n < 100; n++) { ps.setString(name[n]); ps.setLong(id[n]); ps.setInt(salary[n]); ps.executeUpdate(); } //使用Batch PreparedStatement ps = conn.prepareStatement( "INSERT into employees values (?, ?, ?)"); for (n = 0; n < 100; n++) { ps.setString(name[n]); ps.setLong(id[n]); ps.setInt(salary[n]); ps.addBatch(); } ps.executeBatch(); 在例 1中, PreparedStatement被用來屢次執行INSERT語句. 在這裏, 執行了100次INSERT操做, 共有101次網絡往返. 其中,1次往返是預儲statement, 另外100次往返執行每一個迭代. 在例2中, 當在100次INSERT操做中使用addBatch()方法時, 只有兩次網絡往返. 1次往返是預儲statement, 另外一次是執行batch命令. 雖然Batch命令會用到更多的數據庫的CPU週期, 可是經過減小網絡往返,性能獲得提升. 記住, JDBC的性能最大的增進是減小JDBC驅動與數據庫之間的網絡通信. 注:Oracel 10G的JDBC Driver限制最大Batch size是16383條,若是addBatch超過這個限制,那麼executeBatch時就會出現「無效的批值」(Invalid Batch Value) 異常。所以在若是使用的是Oracle10G,在此bug減小前,Batch size須要控制在必定的限度
對於沒必要重複使用和能夠控制輸入值得狀況下statement在性能上仍是比較好的
安全
3.安全方面(防止SQL注入):性能優化
String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";
若是咱們把[' or '1' = '1]做爲varpasswd傳入進來.用戶名hzy,看看會成爲何?
select * from tb_name = 'hzy' and passwd = '' or '1' = '1';
由於'1'='1'確定成立,因此能夠任何經過驗證.更有甚者:
把drop table tb_name;]做爲varpasswd傳入進來,則:
select * from tb_name = '隨意' and passwd = '';drop table tb_name;有些數據庫是不會讓你成功的,但也有不少數據庫就可使這些語句獲得執行.
而若是你使用預編譯語句.你傳入的任何內容就不會和原來的語句發生任何匹配的關係.只要全使用預編譯語句,你就用不着對傳入的數據作任何過慮.而若是使用普通的statement,有可能要對drop,;等作費盡心機的判斷和過慮.
PreparedStatement繼承於Statement,一般的JDBC實現中PreparedStatement最終仍是經過Statement的相關方法來執行SQL的(能夠作少許優化),其最主要的優點在於,能夠減小SQL的編譯錯誤(在JDBC中就能夠捕獲部分異常而不是由數據庫服務器執行時返回錯誤代碼)、增長SQL安全性(減小SQL注入的機會)
參考文章:http://hanzhengyang0126.blog.163.com/blog/static/117503945201111294828507/ 服務器
http://www.cnblogs.com/yezhenhan/archive/2011/04/21/2023195.html網絡