首先來說一下連接了數據庫之后執行的sql語句:通常連接了數據庫之后,我們就會獲得statement 類的對象或者是他的子類的對象(PreparedStatement類),通過這個對象我們就可以利用它提供的方法來操縱數據庫了。
Statement提供了三種方法來執行sql語句:
1,execute:可以執行在任何的sql語句,但是比較麻煩,通常我們不會選擇這一種的但是如果在不清楚SQL語句的類型時,那只能使用execute來執行sql語句了。
2,executeUpdata:主要用於執行DML與DDL語句,執行DML語句返回的是受SQL語句影響的行數,執行DDL語句返回0。
3,executeQuery:只能執行查詢語句。執行后返回代表查詢結果的ResultSet這個集合對象。
下面說一下重點要說的內容:
Statement與PreparedStatement的對象都可以用來執行sql語句但是在許多方面我們還是使用的PreparedStatement類的對象比較多,PreparedStatement是Statement的子類,他可以預編譯sql語句,預編譯后的sql語句儲存在PreparedStatement對象中,然后使用PreparedStatement對象可以多次高效的執行sql語句。
使用PreparedStatement類的對象也有上述的三個執行sql語句的方法,但是這個三個方法無需參數。具體的過程對比請見:http://www.cnblogs.com/duhuo/p/4276226.html
具體如下:
1.使用Statement對象
使用范圍:當執行相似SQL(結構相同,具體值不同)語句的次數比較少
優點:語法簡單
缺點:采用硬編碼效率低,安全性較差。
原理:硬編碼,每次執行時相似SQL都會進行編譯
示例執行過程:
public void exec(Connection conn){ try { Long beginTime = System.currentTimeMillis(); conn.setAutoCommit(false);//設置手動提交 Statement st = conn.createStatement(); for(int i=0;i<10000;i++){ String sql="insert into t1(id) values ("+i+")"; st.executeUpdate(sql); } Long endTime = System.currentTimeMillis(); System.out.println("Statement用時:"+(endTime-beginTime)/1000+"秒");//計算時間 st.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } }
執行時間:Statement用時:31秒
2.預編譯PreparedStatement
使用范圍:當執行相似sql語句的次數比較多(例如用戶登陸,對表頻繁操作..)語句一樣,只是具體的值不一樣,被稱為動態SQL
優點:語句只編譯一次,減少編譯次數。提高了安全性(阻止了SQL注入)
缺點: 執行非相似SQL語句時,速度較慢。
原理:相似SQL只編譯一次,減少編譯次數
事例執行過程:
public void exec2(Connection conn){ try { Long beginTime = System.currentTimeMillis(); conn.setAutoCommit(false);//手動提交 PreparedStatement pst = conn.prepareStatement("insert into t1(id) values (?)"); for(int i=0;i<10000;i++){ pst.setInt(1, i); pst.execute(); } conn.commit(); Long endTime = System.currentTimeMillis(); System.out.println("Pst用時:"+(endTime-beginTime)+"秒");//計算時間 pst.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } }
執行時間:Pst用時:14秒
3.使用PreparedStatement + 批處理
使用范圍:一次需要更新數據庫表多條記錄
優點:減少和SQL引擎交互的次數,再次提高效率,相似語句只編譯一次,減少編譯次數。提高了安全性(阻止了SQL注入)
缺點:
原理:批處理: 減少和SQL引擎交互的次數,一次傳遞給SQL引擎多條SQL。
名詞解釋:
PL/SQL引擎:在oracle中執行pl/sql代碼的引擎,在執行中發現標准的sql會交給sql引擎進行處理。
SQL引擎:執行標准sql的引擎。
事例執行過程:
public void exec3(Connection conn){ try { conn.setAutoCommit(false); Long beginTime = System.currentTimeMillis(); PreparedStatement pst = conn.prepareStatement("insert into t1(id) values (?)"); for(int i=1;i<=10000;i++){ pst.setInt(1, i); pst.addBatch();//加入批處理,進行打包 if(i%1000==0){//可以設置不同的大小;如50,100,500,1000等等 pst.executeBatch(); conn.commit(); pst.clearBatch(); }//end of if }//end of for pst.executeBatch(); Long endTime = System.currentTimeMillis(); System.out.println("pst+batch用時:"+(endTime-beginTime)+"毫秒"); pst.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } }
執行時間:pst+batch用時:485毫秒
總體上來看:
PreparedStatement比使用Statement多了如下三個好處:
1、PreparedStatement預編譯sql語句。性能更好。
2、PreparedStatement無需“拼接”sql語句,編譯更簡單。
3、PreparedStatement可以防止SQL注入,安全性好。