Skip to content

EvalVisitor

wenshao edited this page Nov 24, 2012 · 4 revisions

EvalVisitor是Druid SQL Parser中用于对SQL表达式求值的Visitor。某些场景需要对sql中的部分表达式进行求值然后做特别处理,比如说分库分表时,需要根据其中一个表达式进行求值,以判断其对应的分库分表的规则。

主要接口参数定义如下:

  public interface SQLEvalVisitor extends SQLASTVisitor {
        // 设置求值的参数
        void setParameters(List<Object> parameters);
  }

SQLEvalVisitorUtils

不同的方言的SQLEvalVisitor的实现类是不同的,所以Druid提供了一个易于使用的工具类SQLEvalVisitorUtils。

  public class SQLEvalVisitorUtils {
        public static Object evalExpr(String dbType, String expr, Object... parameters)
  }

第一个参数dbType是数据库的类型,具体的常量值在com.alibaba.druid.util.JdbcConstants中定义。

  public interface JdbcConstants {
        public static final String HSQL              = "hsql";
        public static final String DB2               = "db2";
        public static final String DERBY             = "derby";
        public static final String H2                = "h2"
        public static final String ORACLE            = "oracle";
        public static final String SQL_SERVER        = "sqlserver";
        public static final String SYBASE            = "sybase";
        public static final String POSTGRESQL        = "postgresql";
        public static final String DERBY             = "derby";
  }

第二个参数是需要求值的SQL表达式,比如

3+4
? > 3

第三个参数是需要传入的参数数值,这是一个变长参数,如果第二个参数SQL表达式没有变量,第三个参数是不需要传的。

例子

  // between 
  Assert.assertEquals(false, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? between 1 and 3", 0));
  Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? between 1 and 3", 2));

  // not between
  Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? not between 1 and 3", 0));
  // case when
  Assert.assertEquals(111, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "case ? when 0 then 111 else 222 end", 0));
  
  // in 
  Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? NOT IN (1, 2, 3)", 0));
  Assert.assertEquals(false, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? IN (1, 2, 3)", 0));
  
  // is null
  Assert.assertEquals(false, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? is null", 0));
  Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? is null", (Object) null));
  
  // right function
  Assert.assertEquals("rbar", SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "right('foobarbar', 4)"));
  
  // instr function
  Assert.assertEquals(4, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "instr('foobarbar', 'bar')"));
Clone this wiki locally