如何将表名添加为休眠模板查询的参数之一

Q i*_*Q i 6 java sql spring hibernate

显然,休眠模板查询将字符串参数“ tableName”注入带引号的查询中。这将导致SQL语法语法错误。

如何将表名添加为查询参数之一?

例如,由于表名,以下代码将不起作用:

SQLQuery query = session.createSQLQuery("SELECT ID FROM :tableName");
query.setFlushMode(FlushMode.MANUAL);
query.setReadOnly(true);
query.setParameter("tableName", "STUDENT");
List<Object[]> list = query.list();
Run Code Online (Sandbox Code Playgroud)

Dra*_*vic 5

表名不能在查询中参数化。

您真正想要实现的是构建一个String用于构造查询的:

SQLQuery query = session.createSQLQuery(getIdsQuery("STUDENT"));
...
private String getIdsQuery(String tableName) {
   return "SELECT ID FROM " + tableName;
}
Run Code Online (Sandbox Code Playgroud)

缺乏参数化表名的能力与 Hibernate 无关——数据库不支持它。支持它是没有意义的。

绑定变量的存在主要是出于性能原因。要点是您向数据库发送一个查询(通过 jdbc 驱动程序),其中包含变量的占位符,这些变量将在同一查询的调用之间发生变化:

select id from STUDENT where name = ?
Run Code Online (Sandbox Code Playgroud)

数据库将解析该查询,计算其成本,制定执行计划并将其缓存。查询的后续调用将会快得多,因为所有这些步骤都被跳过并使用缓存的执行计划。

如果表名未知(参数化),数据库如何缓存语句和执行计划?如果不知道从哪里获取数据,它就不会知道获取数据的成本和最佳路径。

此外,如果数据库不知道表中是否实际存在引用的列(如果表名已参数化,则在语句解析时将未知),则在解析查询时数据库将无法完全验证查询。


We *_*org 0

您的 HQL 查询应如下所示:

Query query = session.createQuery("from Conversation as c where c.userConversation.id=:senderid and c.user1Conversation.id=:receiverid");
Run Code Online (Sandbox Code Playgroud)

这里 Conversation 是模型类名,“c”是别名,userConversation 是我拥有的多对一映射。因此,回答您的问题时,您可以按照上述方式输入表名。请不要忘记设置查询参数。

另外,您不需要将 FlushMode 设置为手动,因为您只是阅读列表,之后您甚至不需要调用 session.flush 。其次,为什么要为 query.setParameter 设置硬编码值???

更新

我刚刚读了你的帖子。您的 SQL 查询应该如下所示:

select id,username from Conversation where id=1000;
Run Code Online (Sandbox Code Playgroud)

上面只是一个例子,Conversation仍然是表名。另外,您已将您的帖子标记为 Hibernate,这就是我编写 HQL 查询的原因,根据我的经验,在 HQL 中执行操作要容易得多。