Java中的PreparedStatement,包含数据库和列名称的变量

时间:2016-11-09 18:33:04

标签: java sql

我正在使用PreparedStatement在SQL中编写一些代码来帮助SQL注入。

示例:

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);

它看起来会更好,也更容易阅读。

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

这种编码现在有点陈旧,虽然它可以起作用#34;您是否考虑过使用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>

并调用代码来指定&#34; #value#&#34;令牌:

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

当我检查链接时,这里的Java路由是主动的 - 在:

http://blog.mybatis.org/

但我离开了最初的Wiki示例,因为我觉得它更清晰。

FWIW我一直是这方面的大用户,并且发现它非常适合。正确维护清晰,格式化的纯文本SQL的能力是巨大的。

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

答案 1 :(得分:1)

不,PreparedStatement仅对列值进行参数化,不做其他任何操作。

动态设置表名可能表示存在设计问题,因为通常您会像列名,连接等一样对其进行硬编码。

答案 2 :(得分: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);

如果您从最终用户那里获取表名,那么请使用表名称列入白名单并使用白名单检查您的输入