JsqlParser是什么? http://jsqlparser.sourceforge.net
能做什么? 没有限制,自己想象了。
如果仅作为第三方包直接使用,非常简单,看test case例子就明白。
public void testDrop() throws JSQLParserException { CCJSqlParserManager parserManager = new CCJSqlParserManager(); String statement = "DROP TABLE mytab"; Drop drop = (Drop) parserManager.parse(new StringReader(statement)); assertEquals("TABLE", drop.getType()); assertEquals("mytab", drop.getName()); assertEquals(statement, ""+drop); statement = "DROP INDEX myindex CASCADE"; drop = (Drop) parserManager.parse(new StringReader(statement)); assertEquals("INDEX", drop.getType()); assertEquals("myindex", drop.getName()); assertEquals("CASCADE", drop.getParameters().get(0)); assertEquals(statement, ""+drop); }
但通常用它的理由是----个性化定制、解释sql,那么就要修改它的文法。
最好先熟悉一下javacc,使用起来得心应手,当前为0.70版本。
1.bug修复:
1) ExpressionDeParser#visit(CaseExpression caseExpression)方法,case语句漏掉else:
...
Expression elseExp = caseExpression.getElseExpression();
if( elseExp != null ) {
//zzf 修复bug(漏掉了else关键字)
buffer.append(" ELSE ");
elseExp.accept(this);
}
...
2)SelectDeParser#visit(SubSelect subSelect)方法,子查询有别名,会被漏掉:
super.visit(subSelect);
// zzf 修复bug(增加别名)
String alias = subSelect.getAlias();
if (alias != null) {
buffer.append(" " + alias);
}
其他的XXXDeparser应该还有类似bug。
2.文法增强:
增加对命名参数的支持,如where fname=:name
打开JSqlParserCC.jj(安装eclipse javacc插件),改动两个地方(<span>标签内的,这编辑器格式化把span都显示出来了,本来是想标注红色0xff0000的。),修改完后重新编译即可。
1) RealObjectName语句,增加对 :字符的识别。
String RelObjectName() :
{
Token tk = null;
}
{
(
//zzf
":" tk = < S_IDENTIFIER >
| tk = < S_IDENTIFIER >
| tk = < S_QUOTED_IDENTIFIER >
)
{
return tk.image;
}
}
Expression PrimaryExpression() :
{
Expression retval = null;
Token token = null;
boolean isInverse = false;
String tmp = "";
}
{
(
< K_NULL >
{
retval = new NullValue();
}
| retval = CaseWhenExpression()
| "?"
{
retval = new JdbcParameter();
}
//zzf
| LOOKAHEAD(":")
":" token = < S_IDENTIFIER >
{
retval = new JdbcNamedParameter(token.image);
}
| LOOKAHEAD(
[
"+"
| "-"
]
Function())
...
package net.sf.jsqlparser.expression; /** * 命名参数 * * @author zzf * */ public class JdbcNamedParameter implements Expression { private String name; public JdbcNamedParameter(String name) { this.name = name; } public void accept(ExpressionVisitor expressionVisitor) { expressionVisitor.visit(this); } public String toString() { return ":" + name; } public String getName() { return name; } }
ExpressionVisitor增加接口
public void visit(JdbcNamedParameter jdbcNamedParameter);访问者实现类则根据自己的需要去设置命名参数,如
public void visit(JdbcNamedParameter jdbcNamedParameter) { buffer.append(?); Object value=paramProvider.get(jdbcNamedParameter.getName()); paramList.add(value); }