2014-02-14 59 views
0

我總是閱讀博客Java Revisited,今天我正在閱讀文章Why use PreparedStatement in Java JDBC - Example Tutorial。在一個點上筆者寫了關於查詢的參數,那就是更好的,更安全,更表演使用API​​提供比來連接字符串的參數,並使用下面的例子:即使值始終相同,參數化PreparedStatement是否更好?

SQL查詢1:PreparedStatement的使用字符串連接

String loanType = getLoanType(); 
PreparedStatement pstmt = conn.prepareStatement("select banks from loan where loan_type=" + loanType); 

SQL查詢2:使用PreparedStatement的

PreparedStatement pstmt = conn.prepareStatement("select banks from loan where loan_type=?"); 
pstmt.setString(1, loanType); 

筆者解釋說,通過使用參數,JDBC驅動程序將檢查數據和連接字符串司機d參數化查詢它不會運行發送的SQL,即如果我們有着名的OR 1 = 1,查詢將始終返回true,並且有經典的SQL注入情況。

我不清楚的是,爲什麼一個人比另一個更具表現力,再加上,如果我的價值總是相同的,這是真的嗎?

PreparedStatement pstmt = conn.prepareStatement(select * from users where active = 'S'); 

或者是更多表演用途如下:

PreparedStatement pstmt = conn.prepareStatement(select * from users where active = ?); 
pstmt.setString(1, "S"); 

另一個問題是,在這種情況下,我認爲安全問題是一樣的,因爲沒有參數,通過用戶傳遞有沒有攻擊,對吧?

+1

不幸的是,人們在不解釋原因的情況下保持低調。多麼可憐! –

回答

4

如果參數確實沒有改變,那麼使用文字是可以接受的。但是,根據數據庫平臺的不同,將參數值作爲文字傳入將會導致更改,這可能會導致性能不佳。

當您準備語句時,數據庫將解析SQL並創建執行計劃,以找到結果的最佳方式(使用其優化程序)。這可能涉及幾個步驟,包括「硬」解析和「軟」解析。

當您準備帶有參數化值的語句時,數據庫將解析SQL並緩存解析的執行計劃。然後,您可以多次執行準備好的語句,並且只更改要發送到數據庫的參數值。數據庫可以重新使用緩存的執行計劃,而不必再'硬'解析SQL。

當您使用嵌入式文字參數重複執行SQL語句時,數據庫必須對每次執行執行硬解析,因此;潛在更多的處理時間。

1

安全性是一樣的。使用Prepared Statements的附加安全優勢是驗證用戶輸入以防止SQL注入。在沒有用戶輸入的情況下,不存在安全風險。

如果要使用不同數據多次調用類似的數據庫,使用參數使用單個Prepared Statement而不是使用字符串連接爲每個實例構建新的Prepared Statement會更加高效。如果這只是一次性電話,那麼我無法想象性能會受到很大影響。

1

由於準備工作(包括數據庫引擎對SQL語句的編譯和優化步驟)只能執行一次,因此在多次使用不同參數值的情況下可以獲得性能提升 - 至少在一些JDBC驅動程序/數據庫引擎中。如果您的修正值不是來自用戶,則不需要使用準備好的語句。從性能角度來看,也沒有注入問題。

1

使用PreparedStatement而不是普通Statement的主要優點是參數化查詢 - 這樣你就可以在運行時動態地接受查詢了(這對你來說是一個巨大的優勢需要終端用戶就如何繼續進行指導)。另外,PreparedStatement被設計用來優化運行查詢的執行時間。簡單語句將直接執行傳遞的查詢。因此,由於您使用的是PreparedStatement,因此我建議您使用選項2(從您的問題開始)使用'markers'(?符號)動態傳遞參數是使用PreparedStatement的優勢。

現在,如果參數值永遠不會改變,那麼您該如何繼續下去 - 這只是一個意見問題。在這種情況下,我的建議是使用直線字符串作爲查詢並且不使用參數。

相關問題