表示預編譯的 SQL 語句的對象。
SQL 語句被預編譯并存儲在 PreparedStatement 對象中。然后可以使用此對象多次高效地執行該語句。
Statement是PreparedStatement的父接口,不進行預編譯操作,減少了進行預編譯的開銷.單次運行PreparedStatement要比Statement要慢一些.
PreparedStatement可以實現Statement的所有功能,但是之所以叫它預編譯指令,是因為在創建它的一個對象時可以給定具有一定格式的SQL字符串,然后用它的setXXX方法給指定的SQL語句以填空的方式賦值,具有這樣的特性后,它在多次執行一條固定格式的字符串時就很方便,也更效率.不像Statement那樣每次執行都要先編譯字符串在執行SQL了.
優點:
1. sql語句不是動態創建,可以有變量根據需要自定義SQL語句。 使用Statement 時就直接一句完整的SQL語句傳參。
2. 代碼容易讀,維護方便、例如:
前者:采用Statement 方式,傳參就是一句完整的SQL語句,書寫 和 閱讀令人很頭疼。
后者:采用PreparedStatement 預編譯方式。 雖然代碼多了幾行了,但是閱讀 修改是比較方便的。
3. PreparedStatement 比Statement的性能更好
數據庫自己有種策略 :數據庫編譯器對預編譯語句(例如Statement 和preparedstatement 創建的預編譯語句)都有緩存策略,為了是在下一次的預編譯語句具有相托相同語法匹配時直接執行不需要編譯。 前者相匹配的機會大于后者的,因此在對預編語句的處理中 前者盡可能的提高了性能。
4. PreparedStatement 更具有安全性,能防止SQL注入。
SQL注入攻擊是利用設計上的漏洞,在目標服務器上運行SQL語句進行攻擊,動態生成SQL語句時沒有對用戶輸入的數據進行驗證是SQL注入攻擊得逞的主要原因.
對于JDBC而言,SQL注入攻擊只對Statement有效,對PreparedStatement是無效的,這是因為PreparedStatement不允許在插入時改變查詢的邏輯結構.
( 'amin'or'1'='1 這種巧妙改造SQL的方式,來繞過驗證。 )繞過驗證,但這種手段只對Statement有效,對PreparedStatement無效.因為PreparedStatement 指定了SQL的語法結構了,只是后者加某些變量。
如果有一條SQL語句: "select * from 表 where 用戶名 = '用戶名'"
Statement的SQL語句是這樣寫的: "select * from 表 where 用戶名 = '"+ 變量值 +"'"
PreparedStatement的SQL語句是這樣寫的: "select * from 表 where 用戶名 = ?" 然后對應?賦值
這樣我們就發現輸入 "aa' or '1' = '1"
Statement是將這個和SQL語句做字符串連接到一起執行
PreparedStatement是將 "aa' or '1' = '1" 作為一個字符串賦值給?,做為"用戶名"字段的對應值,顯然這樣SQL注入無從談起了.
下一篇:有關信息安全體系