【问题标题】:Can I use JOOQ as an SQL parser?我可以将 JOOQ 用作 SQL 解析器吗?
【发布时间】:2019-08-16 18:16:31
【问题描述】:

我正在尝试解析 Java 中的 SELECT 语句。我熟悉 JOOQ,并希望使用它。我知道它没有明确设计为 SQL 解析器——它实际上远不止于此,所以我想可能有一种方法可以使用它的内部解析器来解析 SELECT 查询。

我看到了一些关于如何使用访问者模式访问 JOOQ 内部的信息,但我需要使用树状结构在查询内部导航,该结构将允许单独访问查询的每个部分。我不想在所有用例中都使用访问者模式。

这可能吗?我该怎么做呢?

【问题讨论】:

    标签: java jooq


    【解决方案1】:

    从 jOOQ 3.11 开始,虽然您确实可以使用 VisitListener 提取表达式树并对内部进行一些调整(主要取决于通过反射的内部类型),但您目前无法实现。将来会解决这个问题,当表达式树可以通过公共 API 访问时(并且与 SQL 生成逻辑完全分离),但还没有承诺。

    【讨论】:

    • 谢谢@Lukas Eder。你会说使用 JOOQ 的内部实现这个目标会很容易吗(没有公共 API)?你会建议这样做吗?如果是这样,很想听听您建议从哪里开始学习曲线。
    • “你会说使用 JOOQ 的内部实现这个目标很容易吗(没有公共 API)” - 使用反射进行快速而肮脏的工作,是的,绝对是,这是可行的。在进行补丁发布升级时可能会出现收支平衡的风险,但如果您编写一些单元测试来验证您的内部假设,这仍然是可以管理的。 “你会建议这样做吗?” - 当然不是 :) “如果是这样,很想听听你的建议,从哪里开始学习曲线。” - 我不想“记录”这个骇客,所以恐怕你自己一个人......
    • JOOQ 是否/何时正式支持此类功能将在未来再次重新评估。感谢您的帮助。
    • @dblike:是的。这绝对是我们最终想要正式支持的东西。
    【解决方案2】:

    A full-fledged SQL parser is available from DSLContext.parser() and from DSLContext.parsingConnection() (see the manual's section about parsing connections for the latter).

    SQL Parsing API 页面给出了这个简单的例子:

    ResultQuery<?> query = 
    DSL.using(configuration)
       .parser()
       .parseResultQuery("SELECT * FROM (VALUES (1, 'a'), (2, 'b')) t(a, b)");
    

    parseResultQuery 是单个 SELECT 查询所需的方法,如果您可能有多个查询,请使用 parse(String)

    【讨论】:

    • 谢谢,但在文档中似乎没有一种方法可以让我在树状结构中浏览查询的结构。你能建议我如何检查使用此方法解析后查询的不同部分?
    • 嗯,这似乎比我想象的要难(并且没有记录且不受支持,因此它可能会在 jOOQ 更新时中断,并且如果/当它切换到 Jigsaw 模块时中断)。但我能看到的唯一方法是将您的类放入org.jooq.impl 包中,然后您可以将Query 转换为SelectQueryImpl 并使用其get... 方法来获取查询的各个部分:( 因为jOOQ 的作者在 Stack Overflow 上很活跃,希望他能在这里提供更好的选择(如果有的话)。
    猜你喜欢
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-05
    相关资源
    最近更新 更多