【发布时间】:2011-12-03 00:31:53
【问题描述】:
我正在开发和维护一个名为 jOOQ 的数据库抽象库,它旨在将 SQL 作为外部 DSL “内部化”到 Java 中。这项工作的目标是允许类型安全地构造和执行最流行的 RDBMS 的所有可能的 SQL 语法元素。 jOOQ 的内部 DSL 变得越来越复杂,我想正式掌握它。这个想法是我希望能够将某种形式的 SQL 定义作为输入,例如
select ::= subquery [ for-update-clause ]
subquery ::= SELECT [ { ALL | DISTINCT | UNIQUE } ] select-list
[ FROM table-reference ] ..
select-list ::= expression [ [ AS ] alias ] [, expression ... ]
expression ::= ...
alias ::= ...
table-reference ::= ...
输入也可以用 XML 或任何其他描述性元语言定义。一旦我有了那个输入,我想从那个输入生成一组 Java 接口,这些接口对 Java 中定义的语法进行建模。示例接口是:
// The first "step" of query creation is modelled with this interface
interface Select0 {
// The various SELECT keywords are modelled with methods
// returning the subsequent generated syntax-element
Select1 select(Expression...);
Select1 selectAll(Expression...);
Select1 selectDistinct(Expression...);
Select1 selectUnique(Expression...);
}
// The second "step" of query creation is optional, hence it
// inherits from the third "step"
interface Select1 extends Select2 {
// Here a FROM clause may be added optionally
Select2 from(TableReference...);
}
// To keep it simple, the third "step" is the last for this example
interface Select2 extends SelectEnd {
// WHERE, CONNECT BY, PIVOT, UNPIVOT, GROUP BY, HAVING, ORDER BY, etc...
}
使用上述接口,可以在 Java 中构造 SQL 查询,就像今天的 jOOQ 已经允许做的那样:
create.select(ONE, TWO).from(TABLE)...
create.selectDistinct(ONE, TWO).from(TABLE)...
// etc...
另外,我想排除某些特定构建的 some 语法元素。例如。当我构建jOOQ专供MySQL使用时,不需要支持SQL MERGE语句。
是否有任何现有的库实现了这种通用方法,以便正式将 DSL 内部化和外部化到 Java?还是我应该自己滚动?
【问题讨论】:
-
我看看ANTLR,它有几个SQL语法,this PLSQL version看起来很有前途
-
@Sean,我不确定我是否正确理解了 ANTLR,但那是用于字符串的解析和语法检查,对吧?但我想要的是“DSL 内化”。输出应该是一组接口,这使得 SQL 看起来好像可以用 Java 本地编写(jOOQ 今天已经做到了)。我会更新问题。
-
可以,但是你也可以使用 SQL 语法来创建 Java 类
-
亲爱的,那么谢谢你的提示!