我可以将表名作为参数传递给java预处理语句吗?

时间:2012-07-25 07:30:55

标签: java mysql prepared-statement dao tablename

我正在为我的Tomcat服务器应用程序编写一个DAO层IN Java,

我希望使用Prepared Statement包装我的查询(1.解析一次查询,2。防止SQL注入), 我的数据库设计包含每个数据源系统的MyISAM表。通过DBO的大多数查询是使用不同的表名作为参数进行选择。

有些表可以即时创建。

我已经通过很多帖子解释说我可能不会使用表名作为Prepared语句的参数。

我找到了建议使用某种类型的函数(例如mysql_real_escape_string)的解决方案,它可以处理这个参数并将结果作为字符串追加到查询中,

是否有任何内置的Jave库函数可以以最佳优化的方式执行,或者您可能建议在DAO层中执行其他操作(我不希望将自己的任何例程添加到DB) ?

2 个答案:

答案 0 :(得分:4)

您是否可以对表名应用限制?这可能比引用更容易。例如,如果您可以说所有表名都必须匹配[0-9A-Za-z_]+的正则表达式,那么我认为您不需要任何引用。如果你需要空格,你可以使用`table name`轻松使用始终 - 但同样,不必担心“完全”引用。

限制可用内容通常比处理所有可能性简单得多:)

答案 1 :(得分:1)

如果你想要比你准备一个查询更加安全,并用提供的表名来调用它来检查它是否真的存在:

PreparedStatement ps = conn.prepareStatement("SHOW TABLES WHERE tables = ?");
ps.setString(1, nameToCheck);
if(!ps.executeQuery().next())
  throw new RuntimeException("Illegal table name: " + nameToCheck);

WHERE条件可能需要一些修正,因为我目前手指上还没有mysql。)