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表达式没有变量,第三个参数是不需要传的。
例子
// betweenAssert.assertEquals(false, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? between 1 and 3", 0));Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? between 1 and 3", 2));// not betweenAssert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? not between 1 and 3", 0));// case whenAssert.assertEquals(111, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "case ? when 0 then 111 else 222 end", 0));// inAssert.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 nullAssert.assertEquals(false, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? is null", 0));Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? is null", (Object) null));// right functionAssert.assertEquals("rbar", SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "right('foobarbar', 4)"));// instr functionAssert.assertEquals(4, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "instr('foobarbar', 'bar')"));