聊聊mybatis的ParamNameResolver

2023-08-31 14:34:32 浏览数 (2)

在mybatis的interceptor获取MapperMethod.ParamMap这种参数类型时,经常会多出param1,param2,collection,list,array这些参数,这些不是接口自己定义的,而是ParamNameResolver自动添加的

ParamNameResolver

org/apache/ibatis/reflection/ParamNameResolver.java

代码语言:javascript复制
public class ParamNameResolver {

  public static final String GENERIC_NAME_PREFIX = "param";

  /**
   * <p>
   * A single non-special parameter is returned without a name.
   * Multiple parameters are named using the naming rule.
   * In addition to the default names, this method also adds the generic names (param1, param2,
   * ...).
   * </p>
   *
   * @param args
   *          the args
   * @return the named params
   */
  public Object getNamedParams(Object[] args) {
    final int paramCount = names.size();
    if (args == null || paramCount == 0) {
      return null;
    } else if (!hasParamAnnotation && paramCount == 1) {
      Object value = args[names.firstKey()];
      return wrapToMapIfCollection(value, useActualParamName ? names.get(0) : null);
    } else {
      final Map<String, Object> param = new ParamMap<>();
      int i = 0;
      for (Map.Entry<Integer, String> entry : names.entrySet()) {
        param.put(entry.getValue(), args[entry.getKey()]);
        // add generic param names (param1, param2, ...)
        final String genericParamName = GENERIC_NAME_PREFIX   (i   1);
        // ensure not to overwrite parameter named with @Param
        if (!names.containsValue(genericParamName)) {
          param.put(genericParamName, args[entry.getKey()]);
        }
        i  ;
      }
      return param;
    }
  }

  //......

}

getNamedParams方法针对单个参数没有加@Param的场景会调用wrapToMapIfCollection,其他的则使用param1,param2这种,这里用了contains,也就是如果本身命名就有包含param1,param2这种则不会添加

wrapToMapIfCollection

org/apache/ibatis/reflection/ParamNameResolver.java

代码语言:javascript复制
  /**
   * Wrap to a {@link ParamMap} if object is {@link Collection} or array.
   *
   * @param object a parameter object
   * @param actualParamName an actual parameter name
   *                        (If specify a name, set an object to {@link ParamMap} with specified name)
   * @return a {@link ParamMap}
   * @since 3.5.5
   */
  public static Object wrapToMapIfCollection(Object object, String actualParamName) {
    if (object instanceof Collection) {
      ParamMap<Object> map = new ParamMap<>();
      map.put("collection", object);
      if (object instanceof List) {
        map.put("list", object);
      }
      Optional.ofNullable(actualParamName).ifPresent(name -> map.put(name, object));
      return map;
    } else if (object != null && object.getClass().isArray()) {
      ParamMap<Object> map = new ParamMap<>();
      map.put("array", object);
      Optional.ofNullable(actualParamName).ifPresent(name -> map.put(name, object));
      return map;
    }
    return object;
  }

wrapToMapIfCollection对于collection类型添加collection,对于list类型还会添加list参数,如果是array类型则会添加array参数,不过这里使用了ifPresent,也就是如果本身参数名包含了则不会添加

小结

mybatis的ParamNameResolver针对单个参数没有加@Param的场景会调用wrapToMapIfCollection,最多会添加collection、list、array这些参数;其他的则多添加param1,param2这类参数。

0 人点赞