2016-11-09 40 views
0

我正在使用PreparedStatement在SQL中編寫一些代碼以幫助進行SQL注入。Java中的PreparedStatement包含數據庫和列名稱的變量

例子:

stm = c.prepareStatement("UPDATE " 
       + listResults.get(i).get(TemplateFile.TYPEOFPLAY).toLowerCase() 
       + " SET score=? WHERE player_name_fkey=? AND school_name_fkey=? AND tournament_number=?;"); 

stm.setInt(1, Utilities.readNumber(listResults.get(i).get(TemplateFile.TOURNAMENT + j - 1))); 
stm.setString(2, listResults.get(i).get(TemplateFile.NAME)); 
stm.setString(3, listResults.get(i).get(TemplateFile.SCHOOL_NAME)); 
stm.setInt(4, j); 

我的問題是:有沒有辦法讓PreparedStatement對象允許參數(簽名了嗎?)要用於數據庫名稱和列。 例如:

stm = c.prepareStatement("UPDATE ? SET score=? WHERE player_name_fkey=? AND school_name_fkey=? AND tournament_number=?;"); 

stm.setString(1, listResults.get(i).get(TemplateFile.TYPEOFPLAY).toLowerCase()); 
stm.setInt(2, Utilities.readNumber(listResults.get(i).get(TemplateFile.TOURNAMENT + j - 1))); 
stm.setString(3, listResults.get(i).get(TemplateFile.NAME)); 
stm.setString(4, listResults.get(i).get(TemplateFile.SCHOOL_NAME)); 
stm.setInt(5, j); 

它看起來好多了,並且更容易讀爲好。

在此先感謝您的幫助!

+0

謝謝你給出了非常有益的答案! –

回答

1

你不能做到這一點。您只能綁定PreparedStatement上的列值。如果您沒有收到來自最終用戶的表名,你可以在以下

String query = "UPDATE <tablename> SET score=? WHERE player_name_fkey=? AND school_name_fkey=? AND tournament_number=?"; 
query.replace("<tablename>", listResults.get(i).get(TemplateFile.TYPEOFPLAY).toLowerCase()) 
c.prepareStatement(query); 

如果從最終用戶獲取表名,然後有表名的白名單,並與白名單檢查您輸入

1

這種編碼現在有點過時了,儘管它「有效」。你有沒有考慮過使用ORM - 對象/關係映射器 - 比如iBatis或者Hibernate?感謝這是一個比你想要承擔的更大的「重大承諾」變化,但是使用他們自己的例子之一,用一點XML來包含SQL,你可以看看相當純文本的SQL:

<select id="getProduct" parameterClass="java.lang.Long" resultClass="com.example.Product"> 
select PROD_ID as id, 
      PROD_DESC as description 
     from PRODUCT 
    where PROD_ID = #value# 
</select> 

並調用代碼指定 「#值#」 符號:

Product resultProduct = (Product) sqlMapClient.queryForObject("getProduct", 123); 

當我檢查環節,這裏的Java路線保持 - 活躍 - 在:

http://blog.mybatis.org/

但我離開了原來的Wiki例子,因爲我認爲這是一個更清晰的例子。

FWIW我一直是這方面的一個大用戶,並且發現它非常適合。正確保持清晰,格式化的純文本SQL的能力是巨大的。

來自https://en.wikipedia.org/wiki/IBATIS#Usage

1

沒有,PreparedStatement parametrizes僅列值,沒有別的。

設置表名動態可能表明一個設計問題,因爲通常你會硬編碼就像列名,加入等

相關問題