Hibernate 命名查询的表名问题

Posted

技术标签:

【中文标题】Hibernate 命名查询的表名问题【英文标题】:Table Name Troubles With Hibernate Named Query 【发布时间】:2009-08-14 13:40:05 【问题描述】:

我在 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 中找到更好的替代方案。

感谢您的任何意见, 李

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

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

当您创建一个不带引号的名为 wibble 的表时,大多数数据库(如 Oracle)都会将此表创建为全大写“WIBBLE”的表。当你查询它时,你就像在这里一样使用它:

SELECT * FROM wibble

数据库会将其解释为“WIBBLE”,没有问题。

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

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

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

【讨论】:

数据库是 mysql 数据库,它设置为不区分大小写。我不认为这是一个案例问题。我现在只是在尝试创建语句,所以此时我使用的任何情况都应该没问题。似乎只是那些我需要摆脱的引号。

以上是关于Hibernate 命名查询的表名问题的主要内容,如果未能解决你的问题,请参考以下文章

hibernate映射postgreSQL数据库中的表时,表名是大写的时候为啥hibernate不能映射实体

JPQL / Hibernate 查询的动态表名

hibernate怎么区分表名大小写(用的oracle数据库,想让他指向小写的表名)

在 NHibernate 中使用命名参数作为表名

Hibernate,InteliJ - 生成持久性映射,不正确的表名

Spring Boot + JPA + Hibernate 不同的表名前缀