代码之家  ›  专栏  ›  技术社区  ›  Juha Syrjälä

休眠并静态运行HQL查询

  •  5
  • Juha Syrjälä  · 技术社区  · 16 年前

    我想“干运行”Hibernate HQL查询。也就是说,我想知道Hibernate将从给定的HQL查询执行什么样的实际SQL查询,而不实际对实际数据库执行HQL查询。

    我可以访问hibernate表映射、HQL查询字符串和 dialect 为我的数据库。如果需要的话,我也可以访问数据库。

    现在,我如何找出Hibernate可以从HQL生成的所有SQL查询,而不实际对任何数据库执行查询?这有什么工具吗?

    请注意,可以从一个HQL查询生成多个SQL查询,并且生成的SQL查询集可能会根据数据库的内容而有所不同。

    编辑:我不介意连接到数据库获取一些元数据,我只是不想执行查询。

    编辑:我也知道什么限制和偏移应用于查询。我还有将绑定到查询的实际参数。

    2 回复  |  直到 16 年前
        1
  •  5
  •   ChssPly76    16 年前

    简单的回答是“你不能”。答案如下。

    HQLQueryPlan class ,尤其是 getSqlStrings() method SQL,因为在实际执行查询之前需要进一步的预处理(绑定参数、应用限制/偏移量等),但它可能足够接近您想要的。

    这里要记住的是,你需要一个实际的 SessionFactory 实例以进行构造 HQLQueryPlan ,这意味着如果不“连接到任何数据库”,您将无法执行此操作。但是,您可以使用内存中的数据库(SqlLite等),并让Hibernate自动为其创建必要的模式。

    B) 从 ASTQueryTranslatorFactory 这是一个更好的方法。

        2
  •  2
  •   Community Mohan Dere    9 年前

    看看 this answer 用于条件查询。

    对于HQL,这是相同的概念-您必须强制转换到Hibernate实现类和/或访问私有成员,因此它不是一个受支持的方法,但它将与Hibernate的3.2-3.3版本一起工作。以下是从HQL访问查询的代码(查询是session.createQuery(HQL\U字符串)返回的对象):

    Field f = AbstractQueryImpl.class.getDeclaredField("session");
    f.setAccessible(true);
    SessionImpl sessionImpl = (SessionImpl) f.get(query);
    Method m = AbstractSessionImpl.class.getDeclaredMethod("getHQLQueryPlan", new Class[] { String.class, boolean.class });
    m.setAccessible(true);
    HQLQueryPlan plan = (HQLQueryPlan) m.invoke(sessionImpl, new Object[] { query.getQueryString(), Boolean.FALSE });
    for (int i = 0; i < plan.getSqlStrings().length; ++i) {
      sql += plan.getSqlStrings()[i];
    }
    

    可以代理您的会话,然后代理您的查询,这样您就可以在每个查询(hql、sql、criteria)运行之前记录sql和参数,而无需编写查询的代码(只要从您控制的代码中检索初始会话)。