MyBatis源码解析--基础支持层(8)

10.注解模块

对应的annotation包,使得我们可以再Mapper接口上编写简单的数据库SQL。
CRUD相关的注解:@Insert、@Update、@Delete、@Select 四个最主要的,其次还有@UpdateProvider、@DeleteProvider、@SelectProvider、@InsertProvider、@MapKey、@Options、@SelelctKey、@Param。
缓存相关的注解:@CacheNamespace、@Property、@CacheNamespaceRef、@Flush
提取结果集相关的注解:@Results、@Result、@ResultMap、@ResultType、@ConstructorArgs、@Arg、@One、@Many、@TypeDiscriminator、@Case

CRUD相关注解,先从四个最主要的开始,还有个设置参数名称的@Param
@Select

@Documented
@Retention(RetentionPolicy.RUNTIME)
//标注在方法上
@Target(ElementType.METHOD)
public @interface Select {
//查询语句
  String[] value();
}

@Insert

@Documented
@Retention(RetentionPolicy.RUNTIME)
//方法
@Target(ElementType.METHOD)
public @interface Insert {
//插入语句
  String[] value();
}

@Update

@Documented
@Retention(RetentionPolicy.RUNTIME)
//方法
@Target(ElementType.METHOD)
public @interface Update {
//更新语句
  String[] value();
}

@Delete

@Documented
@Retention(RetentionPolicy.RUNTIME)
//方法
@Target(ElementType.METHOD)
public @interface Delete {
//删除语句
  String[] value();
}

@Param 方法参数名的注解 如果不注解默认的就是#{1}以及#{2}等,而注解了可以是@Param(“user”),#{user}

@Documented
@Retention(RetentionPolicy.RUNTIME)
//参数
@Target(ElementType.PARAMETER)
public @interface Param {
  String value();
}

接下来是四个CRUD的provider,这个注解的主要作用是将sql语句通过类方法来指定

@Documented
@Retention(RetentionPolicy.RUNTIME)
//标注在方法上
@Target(ElementType.METHOD)
public @interface SelectProvider {
//对应的类
  Class<?> type();
//对应的方法
  String method();
}

其余3个异曲同工,就省略了。

@MapKey Map结果的键的注解,目的是为了接受多个查询记录到map中
例如:

<select id="getUsers" resultType="java.util.Map"  parameterType="java.util.Map">
select id,name,sex from t_user
</select>
@MapKey("id")
public Map<Integer,Map<String,Object>>getUsers(Map<String,Object>param);
@Documented
@Retention(RetentionPolicy.RUNTIME)
//方法
@Target(ElementType.METHOD)
public @interface MapKey {
  String value();
}

@Options 操作可选项,可以用来返回自增id

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Options {
  public enum FlushCachePolicy {
    /** false for select statement; true for insert/update/delete statement. */
    DEFAULT,
    /** Flushes cache regardless of the statement type. */
    TRUE,
    /** Does not flush cache regardless of the statement type. */
    FALSE
  }
//是否使用缓存
  boolean useCache() default true;
//刷新缓存的策略
  FlushCachePolicy flushCache() default FlushCachePolicy.DEFAULT;
//结果类型
  ResultSetType resultSetType() default ResultSetType.FORWARD_ONLY;
//语句类型
  StatementType statementType() default StatementType.PREPARED;
//加载数量
  int fetchSize() default -1;
//超时时间
  int timeout() default -1;
//是否生成主键
  boolean useGeneratedKeys() default false;
//主键Java类中的字段
  String keyProperty() default "";
//主键在数据库中的字段
  String keyColumn() default "";
  //结果集
  String resultSets() default "";
}

@SelectKey 通过sql语句来获得主键的注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SelectKey {
//return语句
  String[] statement();
//对象的属性
  String keyProperty();
//数据库的字段
  String keyColumn() default "";
//在插入语句执行前还是在执行后
  boolean before();
//返回类型
  Class<?> resultType();
//statementType类型
  StatementType statementType() default StatementType.PREPARED;
}

提取结果集相关的注解
@Results

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Results {
//resultMap的名称
  String id() default "";
  //Result数组
  Result[] value() default {};
}

@Result

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Result {
//是否是id字段
  boolean id() default false;
//数据库中的属性
  String column() default "";
//Java类中的属性
  String property() default "";
//Java Type
  Class<?> javaType() default void.class;
//JDBC Type
  JdbcType jdbcType() default JdbcType.UNDEFINED;
//使用的TypeHandler处理器
  Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;
//One注解
  One one() default @One;
//Many注解
  Many many() default @Many;
}

@One

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface One {
//已映射语句的全限定名
  String select() default "";
//加载类型,延迟加载或者立刻加载
  FetchType fetchType() default FetchType.DEFAULT;

}

@Many 复杂类型的集合属性值的注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Many {
//已映射语句的全限定名
  String select() default "";
//加载类型
  FetchType fetchType() default FetchType.DEFAULT;

}

@ResultMap

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ResultMap {
//对应的结果集
  String[] value();
}

@ResultType

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ResultType {
//类型
  Class<?> value();
}

其余几个基本不用就不解析了

缓存有关的注解
@CacheNamespace 缓存空间配置的注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
//类上
@Target(ElementType.TYPE) 
public @interface CacheNamespace {
//负责储存的Cache实现类
  Class<? extends org.apache.ibatis.cache.Cache> implementation() default PerpetualCache.class;
//负责过期的Cache实现类
  Class<? extends org.apache.ibatis.cache.Cache> eviction() default LruCache.class;
//清空缓存的频率,0代表不清空
  long flushInterval() default 0;
//缓存容器的大小
  int size() default 1024;
//是否序列化
  boolean readWrite() default true;
  //是否阻塞
  boolean blocking() default false;
//property数组
  Property[] properties() default {};
  
}

@Property 属性的注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Property {
  //属性名
  String name();
  //属性值
  String value();
}

@CacheNamespaceRef 指向指定命名空间的注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CacheNamespaceRef {
//指向的类
  Class<?> value() default void.class;
  String name() default "";
}

@Flush 定义在 Mapper 接口中的方法能够调用 SqlSession#flushStatements() 方法

11.Binding模块

对应的是binding包,作用是将用户自定义的Mapper接口和映射文件关联起来,系统可以通过调用自定义 Mapper 接口中的方法执行相应的 SQL 语句完成数据库操作。
MapperRegistry Mapper注册表

public class MapperRegistry {

  private final Configuration config;//config对象,mybatis全局唯一的
  //记录了mapper接口与对应MapperProxyFactory之间的关系
  private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>();

  public MapperRegistry(Configuration config) {
    this.config = config;
  }

  @SuppressWarnings("unchecked")
  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
  //获得MapperProxyFactory
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
    //不存在就抛出异常
    if (mapperProxyFactory == null) {
      throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
    }
    try {
    //创建MapperProxy对象
      return mapperProxyFactory.newInstance(sqlSession);
    } catch (Exception e) {
      throw new BindingException("Error getting mapper instance. Cause: " + e, e);
    }
  }
  //判断是否有Mapper
  public <T> boolean hasMapper(Class<T> type) {
    return knownMappers.containsKey(type);
  }
  
//将mapper接口的工厂类添加到mapper注册中心
  public <T> void addMapper(Class<T> type) {
    if (type.isInterface()) {
    //必须是接口,如果已经添加过就抛出错误
        if (hasMapper(type)) {
          throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
        }
      boolean loadCompleted = false;
      try {
    	//实例化Mapper接口的代理工程类,并将信息添加至knownMappers
        knownMappers.put(type, new MapperProxyFactory<T>(type));
        //解析接口上的注解信息,并添加至configuration对象
        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
        parser.parse();
        loadCompleted = true;
      } finally {
        if (!loadCompleted) {
          knownMappers.remove(type);
        }
      }
    }
  }

  public Collection<Class<?>> getMappers() {
    return Collections.unmodifiableCollection(knownMappers.keySet());
  }

  public void addMappers(String packageName, Class<?> superType) {
  //扫描指定包下的指定类
    ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<>();
    resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
    Set<Class<? extends Class<?>>> mapperSet = resolverUtil.getClasses();
    //遍历添加到knownMappers中
    for (Class<?> mapperClass : mapperSet) {
      addMapper(mapperClass);
    }
  }
//扫描指定包将符合的类添加到knownMappers
  public void addMappers(String packageName) {
    addMappers(packageName, Object.class);
  }
  
}

MapperProxyFactory MapperProxy工厂类

public class MapperProxyFactory<T> {

  //mapper接口的class对象
  private final Class<T> mapperInterface;
//key是mapper接口中的某个方法的method对象,value是对应的MapperMethod,MapperMethod对象不记录任何状态信息,所以它可以在多个代理对象之间共享
  private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<>();

  public MapperProxyFactory(Class<T> mapperInterface) {
    this.mapperInterface = mapperInterface;
  }

  public Class<T> getMapperInterface() {
    return mapperInterface;
  }

  public Map<Method, MapperMethod> getMethodCache() {
    return methodCache;
  }

  @SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy<T> mapperProxy) {
	//创建实现了mapper接口的动态代理对象
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

  public T newInstance(SqlSession sqlSession) {
	 //每次调用都会创建新的MapperProxy对象
    final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

}

MapperProxy 实现了InvocationHandler以及Serializable接口

public class MapperProxy<T> implements InvocationHandler, Serializable {

  private static final long serialVersionUID = -6424540398559729838L;
  private final SqlSession sqlSession;//记录关联的sqlsession对象
  private final Class<T> mapperInterface;//mapper接口对应的class对象;
//key是mapper接口中的某个方法的method对象,value是对应的MapperMethod,MapperMethod对象不记录任何状态信息,所以它可以在多个代理对象之间共享
  private final Map<Method, MapperMethod> methodCache;

  public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {
    this.sqlSession = sqlSession;
    this.mapperInterface = mapperInterface;
    this.methodCache = methodCache;
  }

  @Override
  //增强方法
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      if (Object.class.equals(method.getDeclaringClass())) {//如果是Object本身的方法不增强
        return method.invoke(this, args);
        //如果是默认的方法就用默认的增强方法
      } else if (isDefaultMethod(method)) {
        return invokeDefaultMethod(proxy, method, args);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
    //从缓存中获取mapperMethod对象,如果缓存中没有,则创建一个,并添加到缓存中
    final MapperMethod mapperMethod = cachedMapperMethod(method);
    //调用execute方法执行sql
    return mapperMethod.execute(sqlSession, args);
  }
//从缓存中获取如果不存在就创建进行缓存
  private MapperMethod cachedMapperMethod(Method method) {
    return methodCache.computeIfAbsent(method, k -> new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
  }

  @UsesJava7
  private Object invokeDefaultMethod(Object proxy, Method method, Object[] args)
      throws Throwable {
    final Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class
        .getDeclaredConstructor(Class.class, int.class);
    if (!constructor.isAccessible()) {
      constructor.setAccessible(true);
    }
    final Class<?> declaringClass = method.getDeclaringClass();
    return constructor
        .newInstance(declaringClass,
            MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED
                | MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC)
        .unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args);
  }

  /**
   * Backport of java.lang.reflect.Method#isDefault()
   */
   //针对的是接口中使用Default修饰的方法
  private boolean isDefaultMethod(Method method) {
    return (method.getModifiers()
        & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) == Modifier.PUBLIC
        && method.getDeclaringClass().isInterface();
  }
}

MapperMethod 每个定义的方法对应一个MapperMethod对象

public class MapperMethod {
  //从configuration中获取方法的命名空间.方法名以及SQL语句的类型,内部类
  private final SqlCommand command;
  //封装mapper接口方法的相关信息(入参,返回类型);内部类
  private final MethodSignature method;

  public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {
    this.command = new SqlCommand(config, mapperInterface, method);
    this.method = new MethodSignature(config, mapperInterface, method);
  }

  public Object execute(SqlSession sqlSession, Object[] args) {
    Object result;
    //根据sql语句类型以及接口返回的参数选择调用不同的
    switch (command.getType()) {
      case INSERT: {
    	Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.insert(command.getName(), param));
        break;
      }
      case UPDATE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.update(command.getName(), param));
        break;
      }
      case DELETE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.delete(command.getName(), param));
        break;
      }
      case SELECT:
        if (method.returnsVoid() && method.hasResultHandler()) {//返回值为void
          executeWithResultHandler(sqlSession, args);
          result = null;
        } else if (method.returnsMany()) {//返回值为集合或者数组
          result = executeForMany(sqlSession, args);
        } else if (method.returnsMap()) {//返回值为map
          result = executeForMap(sqlSession, args);
        } else if (method.returnsCursor()) {//返回值为游标
          result = executeForCursor(sqlSession, args);
        } else {//处理返回为单一对象的情况
          //通过参数解析器解析解析参数
          Object param = method.convertArgsToSqlCommandParam(args);
          result = sqlSession.selectOne(command.getName(), param);
          if (method.returnsOptional() &&
              (result == null || !method.getReturnType().equals(result.getClass()))) {
            result = OptionalUtil.ofNullable(result);
          }
        }
        break;
      case FLUSH:
        result = sqlSession.flushStatements();
        break;
      default:
        throw new BindingException("Unknown execution method for: " + command.getName());
    }
    if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
      throw new BindingException("Mapper method '" + command.getName() 
          + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
    }
    return result;
  }

  private Object rowCountResult(int rowCount) {
    final Object result;
    if (method.returnsVoid()) {
      result = null;
    } else if (Integer.class.equals(method.getReturnType()) || Integer.TYPE.equals(method.getReturnType())) {
      result = rowCount;
    } else if (Long.class.equals(method.getReturnType()) || Long.TYPE.equals(method.getReturnType())) {
      result = (long)rowCount;
    } else if (Boolean.class.equals(method.getReturnType()) || Boolean.TYPE.equals(method.getReturnType())) {
      result = rowCount > 0;
    } else {
      throw new BindingException("Mapper method '" + command.getName() + "' has an unsupported return type: " + method.getReturnType());
    }
    return result;
  }

  private void executeWithResultHandler(SqlSession sqlSession, Object[] args) {
    MappedStatement ms = sqlSession.getConfiguration().getMappedStatement(command.getName());
    if (!StatementType.CALLABLE.equals(ms.getStatementType())
        && void.class.equals(ms.getResultMaps().get(0).getType())) {
      throw new BindingException("method " + command.getName() 
          + " needs either a @ResultMap annotation, a @ResultType annotation," 
          + " or a resultType attribute in XML so a ResultHandler can be used as a parameter.");
    }
    Object param = method.convertArgsToSqlCommandParam(args);
    if (method.hasRowBounds()) {
      RowBounds rowBounds = method.extractRowBounds(args);
      sqlSession.select(command.getName(), param, rowBounds, method.extractResultHandler(args));
    } else {
      sqlSession.select(command.getName(), param, method.extractResultHandler(args));
    }
  }

  private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {
    List<E> result;
    Object param = method.convertArgsToSqlCommandParam(args);
    if (method.hasRowBounds()) {
      RowBounds rowBounds = method.extractRowBounds(args);
      result = sqlSession.<E>selectList(command.getName(), param, rowBounds);
    } else {
      result = sqlSession.<E>selectList(command.getName(), param);
    }
    // issue #510 Collections & arrays support
    if (!method.getReturnType().isAssignableFrom(result.getClass())) {
      if (method.getReturnType().isArray()) {
        return convertToArray(result);
      } else {
        return convertToDeclaredCollection(sqlSession.getConfiguration(), result);
      }
    }
    return result;
  }

  private <T> Cursor<T> executeForCursor(SqlSession sqlSession, Object[] args) {
    Cursor<T> result;
    Object param = method.convertArgsToSqlCommandParam(args);
    if (method.hasRowBounds()) {
      RowBounds rowBounds = method.extractRowBounds(args);
      result = sqlSession.<T>selectCursor(command.getName(), param, rowBounds);
    } else {
      result = sqlSession.<T>selectCursor(command.getName(), param);
    }
    return result;
  }

  private <E> Object convertToDeclaredCollection(Configuration config, List<E> list) {
    Object collection = config.getObjectFactory().create(method.getReturnType());
    MetaObject metaObject = config.newMetaObject(collection);
    metaObject.addAll(list);
    return collection;
  }

  @SuppressWarnings("unchecked")
  private <E> Object convertToArray(List<E> list) {
    Class<?> arrayComponentType = method.getReturnType().getComponentType();
    Object array = Array.newInstance(arrayComponentType, list.size());
    if (arrayComponentType.isPrimitive()) {
      for (int i = 0; i < list.size(); i++) {
        Array.set(array, i, list.get(i));
      }
    return array;
    } else {
      return list.toArray((E[])array);
    }
  }

  private <K, V> Map<K, V> executeForMap(SqlSession sqlSession, Object[] args) {
    Map<K, V> result;
    Object param = method.convertArgsToSqlCommandParam(args);
    if (method.hasRowBounds()) {
      RowBounds rowBounds = method.extractRowBounds(args);
      result = sqlSession.<K, V>selectMap(command.getName(), param, method.getMapKey(), rowBounds);
    } else {
      result = sqlSession.<K, V>selectMap(command.getName(), param, method.getMapKey());
    }
    return result;
  }

  public static class ParamMap<V> extends HashMap<String, V> {

    private static final long serialVersionUID = -2212268410512043556L;

    @Override
    public V get(Object key) {
      if (!super.containsKey(key)) {
        throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + keySet());
      }
      return super.get(key);
    }

  }
//内部静态类,SQL命令
  public static class SqlCommand {
	//sql的名称,命名空间+方法名称
    private final String name;
    //获取sql语句的类型
    private final SqlCommandType type;

    public SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method) {
      final String methodName = method.getName();//获取方法名称
      final Class<?> declaringClass = method.getDeclaringClass();
      //从configuration中获取mappedStatement
      MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, declaringClass,
          configuration);
      if (ms == null) {
      //如果有Flush注解,就标注为FLUSH类型
        if(method.getAnnotation(Flush.class) != null){
          name = null;
          type = SqlCommandType.FLUSH;
        } else {
          throw new BindingException("Invalid bound statement (not found): "
              + mapperInterface.getName() + "." + methodName);
        }
      } else {//如果mappedStatement不为空
        name = ms.getId();//获取sql的名称,命名空间+方法名称
        type = ms.getSqlCommandType();//获取sql语句的类型
        if (type == SqlCommandType.UNKNOWN) {
          throw new BindingException("Unknown execution method for: " + name);
        }
      }
    }

    public String getName() {
      return name;
    }

    public SqlCommandType getType() {
      return type;
    }
  //从configuration中获取mappedStatement
    private MappedStatement resolveMappedStatement(Class<?> mapperInterface, String methodName,
        Class<?> declaringClass, Configuration configuration) {
      //sql语句的id为命名空间+方法名字
      String statementId = mapperInterface.getName() + "." + methodName;
      if (configuration.hasStatement(statementId)) {
        return configuration.getMappedStatement(statementId);//从configuration中获取mappedStatement
      } else if (mapperInterface.equals(declaringClass)) {
        return null;
      }
      //遍历父接口,继续获得MappedStatement对象
      for (Class<?> superInterface : mapperInterface.getInterfaces()) {
        if (declaringClass.isAssignableFrom(superInterface)) {
          MappedStatement ms = resolveMappedStatement(superInterface, methodName,
              declaringClass, configuration);
          if (ms != null) {
            return ms;
          }
        }
      }
      return null;
    }
  }
//内部静态类   方法签名
  public static class MethodSignature {

    private final boolean returnsMany;//返回参数是否为集合类型或数组
    private final boolean returnsMap;//返回参数是否为map
    private final boolean returnsVoid;//返回值为空
    private final boolean returnsCursor;//返回值是否为游标类型
    private final boolean returnsOptional;//返回值是否为Optional
    private final Class<?> returnType;//返回值类型
    private final String mapKey;//返回方法上的MapKey,前提是返回类型为Map
    private final Integer resultHandlerIndex;//在方法参数中的位置
    private final Integer rowBoundsIndex;//在方法参数中的位置
    private final ParamNameResolver paramNameResolver;//该方法的参数解析器

    public MethodSignature(Configuration configuration, Class<?> mapperInterface, Method method) {
      //通过类型解析器获取方法的返回值类型
      Type resolvedReturnType = TypeParameterResolver.resolveReturnType(method, mapperInterface);
      if (resolvedReturnType instanceof Class<?>) {
      //普通类
        this.returnType = (Class<?>) resolvedReturnType;
      } else if (resolvedReturnType instanceof ParameterizedType) {
      //泛型
        this.returnType = (Class<?>) ((ParameterizedType) resolvedReturnType).getRawType();
      } else {
      //内部类等
        this.returnType = method.getReturnType();
      }
      //初始化返回值等字段
      this.returnsVoid = void.class.equals(this.returnType);
      this.returnsMany = configuration.getObjectFactory().isCollection(this.returnType) || this.returnType.isArray();
      this.returnsCursor = Cursor.class.equals(this.returnType);
      this.returnsOptional = Jdk.optionalExists && Optional.class.equals(this.returnType);
      this.mapKey = getMapKey(method);
      this.returnsMap = this.mapKey != null;
      this.rowBoundsIndex = getUniqueParamIndex(method, RowBounds.class);
      this.resultHandlerIndex = getUniqueParamIndex(method, ResultHandler.class);
      this.paramNameResolver = new ParamNameResolver(configuration, method);
    }
//获得SQL通用参数
    public Object convertArgsToSqlCommandParam(Object[] args) {
      return paramNameResolver.getNamedParams(args);
    }

    public boolean hasRowBounds() {
      return rowBoundsIndex != null;
    }

    public RowBounds extractRowBounds(Object[] args) {
      return hasRowBounds() ? (RowBounds) args[rowBoundsIndex] : null;
    }

    public boolean hasResultHandler() {
      return resultHandlerIndex != null;
    }

    public ResultHandler extractResultHandler(Object[] args) {
      return hasResultHandler() ? (ResultHandler) args[resultHandlerIndex] : null;
    }

    public String getMapKey() {
      return mapKey;
    }

    public Class<?> getReturnType() {
      return returnType;
    }

    public boolean returnsMany() {
      return returnsMany;
    }

    public boolean returnsMap() {
      return returnsMap;
    }

    public boolean returnsVoid() {
      return returnsVoid;
    }

    public boolean returnsCursor() {
      return returnsCursor;
    }

    /**
     * return whether return type is {@code java.util.Optional}
     * @return return {@code true}, if return type is {@code java.util.Optional}
     * @since 3.5.0
     */
    public boolean returnsOptional() {
      return returnsOptional;
    }
//获得指定参数类型在方法参数中的位置
    private Integer getUniqueParamIndex(Method method, Class<?> paramType) {
      Integer index = null;
      final Class<?>[] argTypes = method.getParameterTypes();
      for (int i = 0; i < argTypes.length; i++) {
        if (paramType.isAssignableFrom(argTypes[i])) {
          if (index == null) {
            index = i;
          } else {
            throw new BindingException(method.getName() + " cannot have multiple " + paramType.getSimpleName() + " parameters");
          }
        }
      }
      return index;
    }
//获得注解的MapKey
    private String getMapKey(Method method) {
      String mapKey = null;
      //必须返回类型是map
      if (Map.class.isAssignableFrom(method.getReturnType())) {
        final MapKey mapKeyAnnotation = method.getAnnotation(MapKey.class);
        if (mapKeyAnnotation != null) {
          mapKey = mapKeyAnnotation.value();
        }
      }
      return mapKey;
    }
  }

}

你可能感兴趣的:(jdbc与mybatis)