簡體   English   中英

准備好的語句中的串聯

[英]Concatenation in prepared statement

我已經為mySQL編寫了通用DAO層(它可以使用Reflection和ResultSetMetaData保存/獲取將Entity擴展到表中的任何類對象)。 我的實現在sql查詢中幾乎沒有串聯。 是浪費了准備好的語句的所有優點,還是我只是失去了連接String的性能,僅此而已?

例如,用於實體刪除的一段代碼:

PreparedStatement prepStatement = con.prepareStatement("DELETE FROM "
                                      + tableName + " WHERE id = ?");
prepStatement.setLong(1, id);

PreparedStatement的主要好處是,當您的代碼的行為與此偽代碼類似時:

PreparedStatement ps = con.prepareStatement("blabalblabla");
for (int i = 0; i < a gazillion times; i++) {
    // Set parameters into ps
    ...
    // execute already prepared statement
    ps.execute();
}

也就是說,您准備一次並執行多次 ,每次使用不同的參數集。 這使驅動程序/數據庫僅執行一次可能耗資巨大的操作(例如解析),然后重新使用該工作。 除此之外,使用PreparedStatement可以解釋為對驅動程序的提示,因為它應該緩存該語句資源或某些東西,因為它將在以后使用,但是我認為它的影響不會像“准備一次”那樣大。執行許多”方法。

您使用串聯添加表名不會禁用JDBC驅動程序所做的優化(如果有)。 但是無論如何,如果您的代碼“一次執行一次准備”比“一次執行多次准備”更多,那么PreparedStatement可能只具有次要的性能優勢。

請注意,以上所有都是高度依賴數據庫/驅動程序的。 例如,Oracle,如果您使用執行好很多 PreparedStatement在我所描述的“准備執行一次多”的方式秒。 最后一條建議是,出於性能和安全性的考慮,除非沒有其他選擇,否則不要忘記連接參數值。

建議使用准備好的語句來提高數據庫性能。 理論上,數據庫驅動程序會緩存准備好的語句(您可能需要啟用對連接對象的緩存)。 我認為串聯不是那么關鍵。 請記住,tableName在驅動程序緩存中可能區分大小寫。

我將檢查您的數據庫驅動程序功能,並且您應該能夠調試驅動程序,並監視數據庫以查看如何處理/執行語句。

您的示例中的變量tableName可能會引入SQL注入漏洞,但它可能是防止這種情況的另一種方法。 例如,

Map<String,String> myTables; // key and value are the same.
tableName = myTables.get(tableName); // safe known value or null.

通常,最好始終使用准備好的語句以避免麻煩。 但是,有時“即時”構建查詢(通常是where查詢中的大多數where )可以節省許多行,否則會接近重復的代碼,因此很難說“從不這樣做”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM