我正在使用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);
它看起来会更好,也更容易阅读。
提前感谢您的帮助!
答案 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路由是主动的 - 在:
但我离开了最初的Wiki示例,因为我觉得它更清晰。
FWIW我一直是这方面的大用户,并且发现它非常适合。正确维护清晰,格式化的纯文本SQL的能力是巨大的。
答案 1 :(得分:1)
不,PreparedStatement
仅对列值进行参数化,不做其他任何操作。
动态设置表名可能表示存在设计问题,因为通常您会像列名,连接等一样对其进行硬编码。
答案 2 :(得分:1)
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);
如果您从最终用户那里获取表名,那么请使用表名称列入白名单并使用白名单检查您的输入