修理JsqlParser

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);
	}
	


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值