代码之家  ›  专栏  ›  技术社区  ›  FoxyBOA

Hibernate:从part解析/转换HQL以获取pairs类别名、类名

  •  3
  • FoxyBOA  · 技术社区  · 17 年前

    例如,对于HQL

    从Foo a内部连接a.test b中选择a.id

    对于结果集来说,这相对容易做到

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

    看见 details here

    2 回复  |  直到 5 年前
        1
  •  4
  •   FoxyBOA    13 年前

    这不是一个很好的方法,但您似乎可以通过一些内部接口获得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客户端通常不可见的子类,并根据猜测不同节点的语义来解释AST。这可能不适用于所有HQL语句,也可能不适用于将来的hibernate版本,或者具有不同的行为。

        2
  •  0
  •   FoxyBOA    17 年前

    我为我的问题找到了正确的解决办法。你最初的帖子几乎是正确的,除了那部分:

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

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