3

谁能指出我,我如何解析/评估 HQL 并获取键是表别名和值的映射 - 完全限定的类名。

例如对于 HQL

SELECT a.id from Foo a INNER JOIN a.test b

我希望有对:

一、package1.Foo

湾。package2.TestClassName

结果集相对容易做

HQLQueryPlan hqlPlan = ((SessionFactoryImpl)sf).getQueryPlanCache().getHQLQueryPlan( getQueryString(), false, ((SessionImpl)session).getEnabledFilters() );
String[] aliases = hqlPlan.getReturnMetadata().getReturnAliases();
Type[] types = hqlPlan.getReturnMetadata().getReturnTypes();

在此处查看详细信息。

4

2 回答 2

4

很难做到这一点,但似乎您可以通过一些内部接口获取 AST 并遍历它:

QueryTranslator[] translators = hqlPlan.getTranslators();
AST ast = (AST)((QueryTranslatorImpl)translators[0]).getSqlAST();
    new NodeTraverser(new NodeTraverser.VisitationStrategy() {
    public void visit(AST node) {
        if(node.getType() == SqlTokenTypes.FROM_FRAGMENT || node.getType() == SqlTokenTypes.JOIN_FRAGMENT) {
            FromElement id = (FromElement)node;
            System.out.println(node+": "+id.getClassAlias()+" - "+id.getClassName());
        }
    }
}).traverseDepthFirst(ast);

所以这似乎是从编译的查询中检索别名映射,但我会非常小心地使用这个解决方案:它将对象类型转换为通常对休眠客户端不可见的子类,并根据猜测不同节点的语义来解释 AST . 这可能不适用于所有 HQL 语句,并且在未来的休眠版本上可能不起作用或具有不同的行为。

于 2008-12-19T15:04:20.573 回答
0

我为我的问题找到了正确的解决方案。除了那部分之外,您的原始帖子几乎是正确的:

if(node.getType() == SqlTokenTypes.FROM_FRAGMENT || node.getType() == SqlTokenTypes.JOIN_FRAGMENT) {
 FromElement id = (FromElement)node;
 System.out.println(node+": "+id.getClassAlias()+" - "+id.getClassName());
}

请更正您的答案,我接受。

于 2008-12-20T08:48:21.423 回答