通过使用 VisitListener 并结合 ExecuteListener,我能够在执行时获取查询中涉及的 Jooq 表 (org.jooq.Table):
import org.jooq.Table;
import org.jooq.VisitContext;
import org.jooq.impl.DefaultVisitListener;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
public class TableCollector extends DefaultVisitListener {
private final static ConcurrentHashMap<String, HashSet<Table<?>>> queryToTables = new ConcurrentHashMap<>();
public static HashSet<Table<?>> getTables(String sqlQuery) {
return queryToTables.get(sqlQuery);
}
private <T> T getDataValue(VisitContext context, String key, T defaultValue) {
T value = (T) context.data(key);
if (value == null) {
value = defaultValue;
}
return value;
}
private <T> T putDataValue(VisitContext context, String key, T value) {
return (T) context.data(key, value);
}
@Override
public void visitStart(VisitContext context) {
Integer stackSize = getDataValue(context, "stackSize", 0);
stackSize++;
putDataValue(context, "stackSize", stackSize);
if (context.queryPart() instanceof Table) {
Table<?> table = (Table<?>) context.queryPart();
HashSet<Table<?>> tables = getDataValue(context, "tables", new HashSet<>());
tables.add(table);
putDataValue(context, "tables", tables);
}
}
@Override
public void visitEnd(VisitContext context) {
Integer stackSize = getDataValue(context, "stackSize", -1);
stackSize--;
putDataValue(context, "stackSize", stackSize);
if (stackSize == 0) {
HashSet<Table<?>> tables = getDataValue(context, "tables", new HashSet<>());
String sql = context.context().render();
if (sql != null) {
queryToTables.put(sql, new HashSet<>(tables));
}
tables.clear();
putDataValue(context, "tables", tables);
}
}
}
import org.jooq.ExecuteContext;
import org.jooq.Query;
import org.jooq.Table;
import org.jooq.impl.DefaultExecuteListener;
import java.util.HashSet;
import java.util.Set;
public class TableExecuteListener extends DefaultExecuteListener {
@Override
public void executeStart(ExecuteContext context) {
super.executeStart(context);
// pull the tables from the {@link TableCollector} for this query
final Set<Table<?>> tablesInQuery = new HashSet<>();
if (context.query() != null) {
tablesInQuery.addAll(TableCollector.getTables(context.sql()));
} else {
for (Query query : context.batchQueries()) {
tablesInQuery.addAll(TableCollector.getTables(query.getSQL()));
}
}
}
}