【问题标题】:how to add table name as one of the parameters of the hibernate template query如何添加表名作为hibernate模板查询的参数之一
【发布时间】:2015-09-18 07:00:00
【问题描述】:

显然,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();

【问题讨论】:

    标签: java sql spring hibernate


    【解决方案1】:

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

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

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

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

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

    select id from STUDENT where name = ?
    

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

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

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

    【讨论】:

    • 这是我正在做的,但是我还是不明白为什么hibernate不支持参数化表名。 :)
    • 这个答案可能导致sql注入,一个非常容易操作的安全漏洞。这也是为什么参数不能用于表名的原因。
    【解决方案2】:

    您的 HQL 查询应如下所示:

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

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

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

    更新

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

    select id,username from Conversation where id=1000;
    

    以上只是一个示例,但 Conversation 仍然是表名。此外,您已将您的帖子标记为 Hibernate,这就是我编写 HQL 查询的原因,在 HQL 中做事要容易得多,这是我所经历的。

    【讨论】:

      【解决方案3】:
      Query query = session.createQuery(String.format("select id from %s", "Student"));
      

      这与第一个答案相同(但使用一些 Java 帮助):您需要构造一个字符串以作为查询传递

      【讨论】:

        猜你喜欢
        • 2015-04-14
        • 2014-06-13
        • 2021-09-04
        • 2010-10-08
        • 2021-05-02
        • 2020-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多