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

主要接口参数定义如下:

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

SQLEvalVisitorUtils

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

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

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

  1. public interface JdbcConstants {
  2. public static final String HSQL = "hsql";
  3. public static final String DB2 = "db2";
  4. public static final String DERBY = "derby";
  5. public static final String H2 = "h2"
  6. public static final String ORACLE = "oracle";
  7. public static final String SQL_SERVER = "sqlserver";
  8. public static final String SYBASE = "sybase";
  9. public static final String POSTGRESQL = "postgresql";
  10. public static final String DERBY = "derby";
  11. }

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

  1. 3+4
  2. ? > 3

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

例子

  1. // between
  2. Assert.assertEquals(false, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? between 1 and 3", 0));
  3. Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? between 1 and 3", 2));
  4. // not between
  5. Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? not between 1 and 3", 0));
  6. // case when
  7. Assert.assertEquals(111, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "case ? when 0 then 111 else 222 end", 0));
  8. // in
  9. Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? NOT IN (1, 2, 3)", 0));
  10. Assert.assertEquals(false, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? IN (1, 2, 3)", 0));
  11. // is null
  12. Assert.assertEquals(false, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? is null", 0));
  13. Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "? is null", (Object) null));
  14. // right function
  15. Assert.assertEquals("rbar", SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "right('foobarbar', 4)"));
  16. // instr function
  17. Assert.assertEquals(4, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "instr('foobarbar', 'bar')"));