Statement用於執行不帶參數的簡單SQL語句,並返回它所生成的結果,每次執行SQL豫劇時,數據庫都要編譯該SQL語句。sql
Satatement stmt = conn.getStatement();
stmt.executeUpdate("insert into client values("aa","aaa")");
PreparedStatement表示預編譯的SQL語句的對象,用於執行帶參數的預編譯的SQL語句。數據庫
CallableStatement則提供了用來調用數據庫中存儲過程的接口,若是有輸出參數要註冊,說明是輸出參數。緩存
雖然Statement對象與PreparedStatement對象可以完成相同的功能,可是相比之下,PreparedStatement具備如下優勢:安全
1.效率更高。服務器
在使用PreparedStatement對象執行SQL命令時,命令會被數據庫進行編譯和解析,並放到命令緩衝區,而後,每當執行同一個PreparedStatement對象時,因爲在緩存區中能夠發現預編譯的命令,雖然它會被再解析一次,可是不會被再一次編譯,是能夠重複使用的,可以有效提升系統性能,所以,若是要執行插入,更新,刪除等操做,最好使用PreparedSatement。鑑於此,PreparedStatement適用於存在大量用戶的企業級應用軟件中。函數
2.代碼可讀性和可維護性更好。性能
下兩種方法分別使用Statement和PreparedStatement來執行SQL語句,顯然方法二具備更好的可讀性。spa
方法1:code
stmt.executeUpdate("insert into t(col1,xol2) values('"+var2+"','"+var2+"')");
方法2:對象
perstmt = con.prepareStatement("insert into tb_name(col1,col2) values(?,?)"); perstmt.setString(1,var1); perstmt.setString(2,var2);
3.安全性更好。
使用PreparedStatement可以預防SQL注入攻擊,所謂SQL注入,指的是經過把SQL命令插入到Web表單提交或者輸入域名或者頁面請求的查詢字符串,最終達到欺騙服務器,達到執行惡意SQL命令的目的。注入只對SQL語句的編譯過程有破壞做用,而執行階段只是把輸入串做爲數據處理,再也不須要對SQL語句進行解析,所以也就避免了相似select * from user where name='aa' and password='bb' or 1=1的sql注入問題的發生。
CallableStatement由prepareCall()方法所建立,它爲全部的DBMS(Database Management System)提供了一種以標準形式調用已存儲過程的方法。它從PreparedStatement中繼承了用於處理輸入參數的方法,並且還增長了調用數據庫中的存儲過程和函數以及設置輸出類型參數的功能。