Mybatis statement-builders文档的坑

前几天把Mybatis升级到3.2.2,发现动态SQL的SqlBuilder/SelectBuilder这几个类应经被弃用,取而代之的是一个叫AbstractSQL的抽象类,打开看源码(什么注释都没有。。。);翻了半天官方文档,发现他有个默认的实现SQL类,新的Mybatis可以通过SQL类来构造动态SQL,详情请见官方文档:

http://mybatis.github.io/mybatis-3/statement-builders.html

 

在参考他的文档的时候,遇到一个奇怪的问题(我参考的是下面这段):

// With conditionals (note the final parameters, required for the anonymous inner class to access them)
public String selectPersonLike(final String id, final String firstName, final String lastName) {
  return new SQL() {{
    SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FIRST_NAME, P.LAST_NAME");
    FROM("PERSON P");
    if (id != null) {
      WHERE("P.ID like ${id}");
    }
    if (firstName != null) {
      WHERE("P.FIRST_NAME like ${firstName}");
    }
    if (lastName != null) {
      WHERE("P.LAST_NAME like ${lastName}");
    }
    ORDER_BY("P.LAST_NAME");
  }}.toString();
}

 

在我运行这段代码的时候,会报错:org.apache.ibatis.builder.BuilderException

 

通过翻看源码org.apache.ibatis.builder.annotation.ProviderSqlSource

 

终于知道了答案:

 

 public ProviderSqlSource(Configuration config, Object provider) {
    String providerMethodName = null;
    try {
      this.sqlSourceParser = new SqlSourceBuilder(config);
      this.providerType = (Class<?>) provider.getClass().getMethod("type").invoke(provider);
      providerMethodName = (String) provider.getClass().getMethod("method").invoke(provider);

      for (Method m : this.providerType.getMethods()) {
        if (providerMethodName.equals(m.getName())) {
          if (m.getParameterTypes().length < 2
              && m.getReturnType() == String.class) {
            this.providerMethod = m;
            this.providerTakesParameterObject = m.getParameterTypes().length == 1;
          }
        }
      }
    } catch (Exception e) {
      throw new BuilderException("Error creating SqlSource for SqlProvider.  Cause: " + e, e);
    }
    if (this.providerMethod == null) {
      throw new BuilderException("Error creating SqlSource for SqlProvider. Method '"
          + providerMethodName + "' not found in SqlProvider '" + this.providerType.getName() + "'.");
    }
  }

 上面代码10-11行指出:方法返回值必须是String,而且参数只能是0或者一个。于是把上面的一窜参数改成:final Map<String, Object> paramMap,测试通过,mybatis会自动把参数封装到Map里面去。

 

官方文档真是坑爹,希望后面的伙伴们少走弯路。

 

本文出自ITEYE BLOG,转载请注明出处:

http://qurey.iteye.com/blog/1944785

你可能感兴趣的:(Mybatis statement-builders文档的坑)