使用Hibernate命名查询的表名称故障

时间:2009-08-14 13:40:06

标签: java hibernate named-query

我在Hibernate中有以下命名查询:

<sql-query name="CreateLogTable">
  CREATE TABLE IF NOT EXISTS :tableName (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    `url` VARCHAR (750) NOT NULL, 
    `query` VARCHAR (500), 
    `ipaddress` VARCHAR (39), 
    `datetime` DATETIME NOT NULL, 
    `hits` MEDIUMINT UNSIGNED DEFAULT '0' NOT NULL, 
    `path_id` VARCHAR (8), 
    PRIMARY KEY(`id`),
    UNIQUE(`id`),
    INDEX(`id`,`query`,`datetime`,`path_id`)
  ) TYPE = MyISAM
</sql-query>

然后我尝试使用以下行执行此行(常量指向正确的项目):

getSession().getNamedQuery(CREATE_SQL).setString(CREATE_SQL_TABLE_NAME_PARAM, "wibble").executeUpdate();

现在当我执行代码时,我得到一个关于表名的SQL错误,该错误是由引号括起来的:

CREATE TABLE IF NOT EXISTS 'wibble' (

如果我接受生成的查询并在表名周围没有引号的情况下尝试它,则查询工作正常。这只是引起我问题的引用。

所以我的问题是:我需要使用什么而不是setString来确保我的参数不被引号括起来?我试过setParameter没有运气,我无法从API中发现任何更好的选择。

感谢任何输入, 利

2 个答案:

答案 0 :(得分:2)

我认为您不能将命名参数用于表名等数据库标识符。只有值表达式。如果允许,它会使您容易受到SQL注入攻击。作为替代方案,您可以使用Java构建查询。

答案 1 :(得分:0)

您使用的数据库类型是什么?有些数据库区分大小写(实际上大多数都是微软的)。所以名为'wibble'的表与'WiBbLe'不同,仍然与'WIBBLE'不同。

当您创建一个名为wibble且没有引号的表时,大多数数据库(如Oracle)会将其创建为以全部大写“WIBBLE”命名的表。当您查询它时,您可以像在此处一样使用它:

SELECT * FROM wibble

数据库会将此解释为“WIBBLE”并且没有问题。

持久性提供程序似乎总是把它放在引号中。要使引用的名称与创建的名称相同,您应该将其大写。所以试试这个:

getSession().getNamedQuery(CREATE_SQL).setString(CREATE_SQL_TABLE_NAME_PARAM, "WIBBLE").executeUpdate();

这应该创建带有'WIBBLE'的语句,该语句应该与没有引号的wibble相同。