根据您的问题,我假设您想使用 jOOQ parser API 解析您的 SQL 字符串,然后从 jOOQ 的元模型中提取列名。
使用 jOOQ 3.16 查询对象模型 API
jOOQ 3.16 引入了a new, experimental (as of 3.16) query object model API, which can be traversed,它将在接下来的几个小版本中得到增强。从 jOOQ 3.17 开始,解析 SQL 时:
Query query = ctx.parser().parseQuery(sql);
// The QOM.CreateTable type is available in jOOQ 3.17+
if (query instanceof QOM.CreateTable ct) {
for (TableElement te : ct.$tableElements()) {
if (te instanceof Field<?> f) {
System.out.println(f.getName());
}
}
}
早期 jOOQ 版本中的替代方法
目前(从 jOOQ 3.11 开始),元模型无法通过公共 API 获得。您只能通过使用VisitListener 来访问它,这是一个在元模型中包含的每个QueryPart(即表达式树元素)上调用的SPI。这个示例实现可以给你一个想法:
import org.jooq.*;
import org.jooq.impl.*;
public class Columns {
public static void main(String[] args) {
var parser =
DSL.using(new DefaultConfiguration().set(new DefaultVisitListener() {
@Override
public void visitStart(VisitContext ctx) {
if (ctx.queryPart() instanceof Field
&& !(ctx.queryPart() instanceof Param))
System.out.println(((Named) ctx.queryPart()).getQualifiedName());
}
})).parser();
System.out.println("Query 1");
System.out.println("-------");
parser.parseQuery("create table `filetest`(`id` int not null auto_increment, `Meno` varchar(21) null, `Priezvisko` varchar(24) null, `Vek` int null, constraint `pk_filetest` primary key (`id`))").getSQL();
System.out.println();
System.out.println("Query 2");
System.out.println("-------");
parser.parseQuery("insert into `filetest` (`Meno`, `Priezvisko`, `Vek`) values ('Jack', 'Daniels', '21')").getSQL();
}
}
它将打印:
Query 1
-------
"id"
"Meno"
"Priezvisko"
"Vek"
"id" -- Field is referenced again from the constraint
Query 2
-------
"Meno"
"Priezvisko"
"Vek"
当然,另一种选择是使用反射来访问 jOOQ 的内部。