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')"));