很明显,hibernate 模板查询将字符串参数“tableName”注入(inject)到带有引号的查询中。这将导致 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();
最佳答案
表名不能在查询中参数化。
您真正想要实现的是构建一个 String
,它将用于构造查询:
SQLQuery query = session.createSQLQuery(getIdsQuery("STUDENT"));
...
private String getIdsQuery(String tableName) {
return "SELECT ID FROM " + tableName;
}
缺少参数化表名的能力与 Hibernate 无关——数据库不支持它。支持它是没有意义的。
绑定(bind)变量的存在主要是出于性能原因。重点是您向数据库发送一个查询(通过 jdbc 驱动程序),其中包含变量的占位符,这些变量将在相同查询的调用之间发生变化:
select id from STUDENT where name = ?
数据库会解析这个查询,计算成本,制定执行计划并缓存。查询的后续调用会快得多,因为所有这些步骤都被跳过并且 cached execution plan被使用。
如果表名未知(参数化),数据库如何缓存语句和执行计划?如果它不知道从哪里获取数据,它就不知道获取数据的成本和最佳路径。
此外,如果数据库不知道引用的列是否确实存在于表中(如果表名已参数化,则在语句解析时将未知),则数据库在解析查询时将无法完全验证查询。
关于java - 如何将表名添加为 hibernate 模板查询的参数之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31155920/