框架改造之mybatis问题Available parameters are [arg0,collection,list]

1,799 阅读1分钟

公司框架改造之后个别查询报错,错误如下

Parameter "xxx" not found.Available parameters are [arg0,collection,list]

调试代码如下:

public ParamNameResolver(Configuration config, Method method) {
  this.useActualParamName = config.isUseActualParamName();
  final Class<?>[] paramTypes = method.getParameterTypes();
  final Annotation[][] paramAnnotations = method.getParameterAnnotations();
  final SortedMap<Integer, String> map = new TreeMap<>();
  int paramCount = paramAnnotations.length;
  // get names from @Param annotations
  for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) {
    if (isSpecialParameter(paramTypes[paramIndex])) {
      // skip special parameters
      continue;
    }
    String name = null;
    for (Annotation annotation : paramAnnotations[paramIndex]) {
      if (annotation instanceof Param) {
        hasParamAnnotation = true;
        name = ((Param) annotation).value();
        break;
      }
    }
    if (name == null) {
      // @Param was not specified.
      if (useActualParamName) {
        name = getActualParamName(method, paramIndex);
      }
      if (name == null) {
        // use the parameter index as the name ("0", "1", ...)
        // gcode issue #71
        name = String.valueOf(map.size());
      }
    }
    map.put(paramIndex, name);
  }
  names = Collections.unmodifiableSortedMap(map);
}

由于代码中只有单参数,沒有使用@Param注解,并且使用的编译插件不是springboot-starter-parent中的插件。其实这边主要时parameters这个参数设置为true即可

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <parameters>true</parameters>
    </configuration>
</plugin>

此参数为javac的参数javac -parameters 不加此参数编译出来的的参数为arg0,arg1,加了此参数则就会使用参数名。 而mybatis

if (useActualParamName) {
  name = getActualParamName(method, paramIndex);
}

useActualParamName此属性为true时就会通过jvm获取到实际参数名称。所以就产生了如上报错。 当加上了这个参数之后就正常了,但是问题还没结束,这个外包项目有个自己写的db框架。第二天其它的项目又出了个问题 Parameter "arg0" not found.Available parameters are [param1,xxx,yyy,param2]调试发现代码如下

public class BaseSQLBuilder {

    public final static String SCRIPT_PREFIX = "<script>";
    public final static String SCRIPT_SUFFIX = "</script>";
    public final static String ARG_0 = "arg0";

    public String buildBySQL(Map<String, Object> params) {
        Assert.notEmpty(params, "Parameter params cannot be null or empty");

        return joinScriptXml(params.get(ARG_0) + StringUtils.EMPTY);
    }

    private String joinScriptXml(String value) {
        StringBuilder builder = new StringBuilder();
        builder.append(SCRIPT_PREFIX).append(value).append(SCRIPT_SUFFIX);

        return builder.toString();
    }
}

这个db框架构建sql时偷了个懒写死了取arg0怎么办呢? 没关系呢,这个只是编译阶段的产物,所以单独把这个db框架不加parameter参数编译即可。