任何人都可以指出我,我如何解析/评估HQL并获取map是表别名和值的地图 - 全限定类名。
E.g。对于HQL
从Foo a INNER JOIN a.test b
中选择a.id.
我希望有成对:
a,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();
请参阅details here。
答案 0 :(得分: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);
所以这似乎从编译的查询中检索别名映射,但我会非常小心地使用这个解决方案:它将对象强制转换为通常对hibernate-client不可见的子类,并基于猜测语义来解释AST。不同的节点。这可能不适用于所有HQL语句,并且可能在将来的hibernate版本上不起作用或具有不同的行为。
答案 1 :(得分:0)
我为我的问题找到了正确的解决方案。您的原始帖子几乎正确,但该部分除外:
if(node.getType() == SqlTokenTypes.FROM_FRAGMENT || node.getType() == SqlTokenTypes.JOIN_FRAGMENT) {
FromElement id = (FromElement)node;
System.out.println(node+": "+id.getClassAlias()+" - "+id.getClassName());
}
请更正你的回答,我接受了。