JDBC中Statement与PreparedStatement的区别
http://www.blogjava.net/redcoatjk/archive/2012/07/20/383583.html
1. statement每次執行sql語句,相關數據庫都要執行sql語句的編譯;preparedstatement是預編譯的, 采用Cache機制(預編譯語句,放在Cache中,下次執行相同SQL語句時,則可以直接從Cache中取出來,有利于sql生成查詢計劃。),對于批量處理可以大大提高效率. 也叫JDBC存儲過程。
例如,如果要執行兩條sql語句
SELECT colume FROMTABLEWHERE colume=1;SELECT colume FROMTABLEWHERE colume=2;會生成兩個執行計劃
一千個查詢就生成一千個執行計劃!
PreparedStatement用于使用綁定變量重用執行計劃
SELECT colume FROMTABLEWHERE colume=:x;通過set不同數據只需要生成一次執行計劃,可以重用
是否使用綁定變量對系統影響非常大,生成執行計劃極為消耗資源
兩種實現 速度差距可能成百上千倍
后者使用了PreparedStatement對象,而前者是普通的Statement對象。PreparedStatement對象不僅包含了SQL語句,而且大多數情況下這個語句已經被預編譯過,因而當其執行時,只需DBMS運行SQL語句,而不必先編譯。當你需要執行Statement對象多次的時候,PreparedStatement對象將會大大降低運行時間,當然也加快了訪問數據庫的速度。
這種轉換也給你帶來很大的便利,不必重復SQL語句的句法,而只需更改其中變量的值,便可重新執行SQL語句。選擇PreparedStatement對象與否,在于相同句法的SQL語句是否執行了多次,而且兩次之間的差別僅僅是變量的不同。如果僅僅執行了一次的話,在對數據庫只執行一次性存取的時侯,用 Statement 對象進行處理,PreparedStatement 對象的開銷比Statement大,對于一次性操作并不會帶來額外的好處。
2. PrepareStatement中執行的SQL語句中是可以帶參數的,也就是說可以替換變量,盡量采用使用?號的方式傳遞參數,增加代碼的可讀性又可以預編譯加速;而Statement則不可以。
3.防止SQL注入。在SQL中包含特殊字符或SQL的關鍵字(如:’ or 1 or ‘)時,Statement將出現不可預料的結果(出現異常或查詢的結果不正確),可用PreparedStatement來解決。
SQL注入或者說SQL注入***就是利用Statement的漏洞完成的,例如用個用戶登錄,那么form表單有用戶名和密碼那么我提交時,在用戶名輸入框內 輸入 “aaa’ or ’a’=’a” 密碼框隨便輸入,那么這樣意味著 sql的查詢語言就是 “select * from 表 where 用戶名=’aaa’ or ’a’=’a’ and 密碼=’123’ ?”,這樣查詢出來所有的數據或者是混亂。那么不被授權的用戶照樣可以登錄,豈不是被黑了?!實際中現在java程序員早都不用這種方式寫查詢了,一般都用PreparedStatement來查詢,或干脆就用hibernate之類的持久層框架,這樣通過sql注入就無從談起了。、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
1:創建時的區別:
? ?Statement stm=con.createStatement();
? ? PreparedStatement pstm=con.prepareStatement(sql);
執行的時候:
? ? ?stm.execute(sql);
? ? ?pstm.execute(); ?
2: pstm一旦綁定了SQL,此pstm就不能執行其他的Sql,即只能執行一條SQL命令。
stm可以執行多條SQL命令。
3: 對于執行同構的sql(只有值不同,其他結構都相同),用pstm的執行效率比較的高,對于異構的SQL語句,Statement的執行效率要高。
4:當需要外部變量的時候,pstm的執行效率更高.
下面是一個statement的列子 :
Java代碼
package com.JDBC.proc; ?
import java.sql.*; ?
public class StatementTest { ?
? ? ?public static void main(String args[]){ ?
? ? ? ? ?Connection conn=null; ?
? ? ? ? ?Statement stm=null; ?
? ? ? ? ?ResultSet rs=null; ?
? ? ? ? ?try { ?
? ? ? ? ? ? ?conn=DBTool.getConnection(); ?
? ? ? ? ? ? ?String sql="select EmpNo,EName from emp " + ?
? ? ? ? ? ? ? ? ? ? ?"where empNo=7499"; ?
? ? ? ? ? ? ?stm=conn.createStatement(); ?
? ? ? ? ? ? ?rs=stm.executeQuery(sql); ?
? ? ? ? ? ? ?while(rs.next()){ ?
? ? ? ? ? ? ? ? ?System.out.println(rs.getInt(1)+"---"+rs.getString(2)); ?
? ? ? ? ? ? ?} ?
? ? ? ? ?} catch (SQLException e) { ?
? ? ? ? ? ? ?e.printStackTrace(); ?
? ? ? ? ?} catch (Exception e) { ?
? ? ? ? ? ? ?e.printStackTrace(); ?
? ? ? ? ?}finally{ ?
? ? ? ? ? ? ?DBTool.release(rs, stm, conn); ?
? ? ? ? ? ? ?} ?
? ? ?} ?
}
他的主要作用闡述Statement的用法。
下面是關于prepareStatement的列子:
Java代碼
package com.JDBC.proc; ?
import java.sql.*; ?
public class PrepareStatement { ?
? ? ?public static void main(String[] args){ ?
? ? ? ? ?Connection conn=null; ?
? ? ? ? ?PreparedStatement psmt=null; ?
? ? ? ? ?ResultSet rs=null; ?
? ? ? ? ?try { ?
? ? ? ? ? ? ?conn=DBTool.getConnection(); ?
? ? ? ? ? ? ?String sql="select EmpNo,Ename " + ?
? ? ? ? ? ? ? ? ? ? ?"from emp " + ?
? ? ? ? ? ? ? ? ? ? ?"where EmpNo=?"; ?
? ? ? ? ? ? ?psmt=conn.prepareStatement(sql); ?
? ? ? ? ? ? ?psmt.setInt(1, 7499); ?
? ? ? ? ? ? ?rs=psmt.executeQuery(); ?
? ? ? ? ? ? ?while(rs.next()){ ?
? ? ? ? ? ? ? ? ?System.out.println(rs.getInt(1)+"---"+rs.getString(2)); ?
? ? ? ? ? ? ?} ?
? ? ? ? ?} catch (SQLException e) { ?
? ? ? ? ? ? ?// TODO Auto-generated catch block ?
? ? ? ? ? ? ?e.printStackTrace(); ?
? ? ? ? ?} catch (Exception e) { ?
? ? ? ? ? ? ?e.printStackTrace(); ?
? ? ? ? ?}finally{ ?
? ? ? ? ? ? ?DBTool.release(rs, psmt, conn); ?
? ? ? ? ?} ?
? ? ?} ?
}
轉載于:https://blog.51cto.com/5563447/1294837
總結
以上是生活随笔為你收集整理的JDBC中Statement与PreparedStatement的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《地狱男爵》系列电影宣布再次重启,《怒火
- 下一篇: URVE Board Pi 单板计算机发