【Statement和PreparedStatement有什麽區別?哪個性能更好?預編譯語句,防止sql註入問題】
答:與Statement相比,①PreparedStatement接口代表預編譯的語句,它主要的優勢在於可以減少SQL的編譯錯誤並增加SQL的安全性(減少SQL註射攻擊的可能性);②PreparedStatement中的SQL語句是可以帶參數的,避免了用字符串連接拼接SQL語句的麻煩和不安全;③當批量處理SQL或頻繁執行相同的查詢時,PreparedStatement有明顯的性能上的優勢,由於數據庫可以將編譯優化後的SQL語句緩存起來,下次執行相同結構的語句時就會很快(不用再次編譯和生成執行計劃)。
SQL註入問題
假設有登錄案例SQL語句如下:
SELECT * FROM 用戶表 WHERE NAME = 用戶輸入的用戶名 AND PASSWORD = 用戶輸的密碼;
此時,當用戶輸入正確的賬號與密碼後,查詢到了信息則讓用戶登錄。但是當用戶輸入的賬號為XXX 密碼為:XXX’ OR ‘a’=’a時,則真正執行的代碼變為:
SELECT * FROM 用戶表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’ OR ’a’=’a’;
此時,上述查詢語句時永遠可以查詢出結果的。那麽用戶就直接登錄成功了,顯然我們不希望看到這樣的結果,這便是SQL註入問題。
為此,我們使用PreparedStatement來解決對應的問題。
API詳解:預處理對象
使用PreparedStatement預處理對象時,建議每條sql語句所有的實際參數,都使用逗號分隔。
String sql = "insert into sort(sid,sname) values(?,?)";;
PreparedStatement預處理對象代碼:
PreparedStatement psmt = conn.prepareStatement(sql)
常用方法:
- 執行SQL語句:
l int executeUpdate(); --執行insert update delete語句.
l ResultSet executeQuery(); --執行select語句.
l boolean execute(); --執行select返回true 執行其他的語句返回false.
- 設置實際參數
l void setXxx(int index, Xxx xx) 將指定參數設置為給定Java的xx
值。在將此值發送到數據庫時,驅動程序將它轉換成一個 SQL Xxx
類型
值。
例如:
setString(2, "家用電器") 把SQL語句中第2個位置的占位符? 替換成實際參數 "家用電器"
【Statement和PreparedStatement有什麽區別?哪個性能更好?預編譯語句,防止sql註入問題】