【问题标题】:Get table/column metadata from JOOQ parser result从 JOOQ 解析器结果中获取表/列元数据
【发布时间】:2019-05-10 19:02:11
【问题描述】:

使用 JOOQ 解析器 API,我能够解析以下查询并从生成的 Query 对象中获取参数映射。由此可知,有一个参数,其名称为“某物”。

但是,我无法弄清楚如何确定参数“something”被分配给名为“BAZ”的列并且该列是表“BAR”的一部分。

解析器 API 是否有办法获取与每个参数关联的表/列元数据?

String sql = "SELECT A.FOO FROM BAR A WHERE A.BAZ = :something";

DSLContext context = DSL.using...
Parser parser = context.parser();
Query query = parser.parseQuery(sql);


Map<String, Param<?>> params = query.getParams();

【问题讨论】:

    标签: java sql jooq


    【解决方案1】:

    从 jOOQ 3.16 开始

    jOOQ 3.16 引入了一个新的、实验性的(自 3.16 起)查询对象模型 API,它可以被遍历,参见:

    具体可以这样写:

    List<QueryPart> parts = query.$traverse(
        Traversers.findingAll(q -> q instanceof Param)
    );
    

    或者,为了方便地生成您想要的类型:

    Map<String, Param<?>> params = query.$traverse(Traversers.collecting(
        Collectors.filtering(q -> q instanceof Param,
            Collectors.toMap(
                q -> ((Param<?>) q).getParamName(),
                q -> (Param<?>) q
            )
        )
    ));
    

    Collectors.toMap() 调用可以包含 mergeFunction,以防您有两次相同的参数名称。

    Pre jOOQ 3.16

    从 jOOQ 3.11 开始,可用于访问内部表达式树的 SPI 是 VisitListener SPI,您必须在解析之前将其附加到您的 context.configuration()。然后,每当您遍历该表达式树时都会调用它,例如在您的query.getParams() 电话中。

    但是,需要进行大量手动管道操作。例如,VisitListener 只会将A.BAZ 视为列引用,而不会直接知道A 是重命名的表BAR。当您访问 BAR A 表达式时,您必须自己跟踪此类重命名。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 2013-05-06
      • 2018-01-02
      相关资源
      最近更新 更多