2016-11-09 37 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仅列值,没有别的。

设置表名动态可能表明一个设计问题,因为通常你会硬编码就像列名,加入等

相关问题