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;
}
}
2) PrimaryExpression增加命名参数表达式的对象创建,另外新建JdbcNamedParameter类。
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())
...
JdbcNamedParameter类
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);
}