如果从简单的SQL语句中获取表名,那么可以通过不严谨的关键字匹配的方式获取或者正则表达式的方式获取表名。但是这种做法不具有通用性,遇到复杂的SQL语句就会存在BUG。

严谨的做法当然是通过SQL分析工具分析SQL结构并获取SQL信息,Jsqlparser就是这样的工具,为我们的SQL分析提供了便利。下面通过一个简单的例子可以了解到Jsqlparser的实现机制,举一反三,更多的应用都是可以做到的。//实现从SQL中提取表名

public static final List getTables(String sql) {

CCJSqlParserManager parserManager = new CCJSqlParserManager();

Statement stmt;

try {

//解析SQL语句

stmt = parserManager.parse(new StringReader(sql));

} catch (JSQLParserException e) {

return null;

}

final List tableNames = new ArrayList();

//使用visitor模式访问SQL的各个组成部分

stmt.accept(new MyStatementVisitor(tableNames));

return tableNames;

}

static class MySelectVisitor implements SelectVisitor {

List tableNames;

public MySelectVisitor(List tableNames) {

this.tableNames = tableNames;

}

@Override

public void visit(PlainSelect ps) {

FromItemVisitor fromItemVisitor = new FromItemVisitor() {

@Override

public void visit(Table table) {

tableNames.add(table.getName());

}

@Override

public void visit(SubSelect ss) {

ss.getSelectBody().accept(new MySelectVisitor(tableNames));

}

@Override

public void visit(SubJoin sj) {

sj.getLeft().accept(this);

sj.getJoin().getRightItem().accept(this);

}

};

//访问select中的from部分,这里获取到第一个表名

ps.getFromItem().accept(fromItemVisitor);

//访问select中的join部分,这里获取到第二个表名

List joins = ps.getJoins();

if (joins != null) {

for (Join join : joins) {

join.getRightItem().accept(fromItemVisitor);

}

}

}

//忽略

@Override

public void visit(Union union) {

}

}

static class MyStatementVisitor implements StatementVisitor {

List tableNames;

public MyStatementVisitor(List tableNames) {

this.tableNames = tableNames;

}

//访问select语句

public void visit(Select select) {

//访问select的各个组成部分

select.getSelectBody().accept(new MySelectVisitor(tableNames));

}

//访问delete语句

public void visit(Delete delete) {

tableNames.add(delete.getTable().getName());

}

//访问update语句

public void visit(Update update) {

tableNames.add(update.getTable().getName());

}

//访问insert语句

public void visit(Insert insert) {

tableNames.add(insert.getTable().getName());

}

//访问replace,忽略

public void visit(Replace replace) {

}

//访问drop,忽略

public void visit(Drop drop) {

}

//访问truncate,忽略

public void visit(Truncate truncate) {

}

//访问create,忽略

public void visit(CreateTable arg0) {

}

}

public static void main(String[] args) throws JSQLParserException {

System.out.println(getTables("select * from  (select * from table_a left outer join table_b on table_a.aa=table_b.bb)"));

//输出结果:[table_a, table_b]

}

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐