表示預編譯的 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注入無從談起了.