开始mybaits源码学习 1

    从org.apache.ibatis.binding.MapperProxy开始。

    MapperProxy是一个代理类实现java标准代理接口,私有构造,另提供一个获得动态代理的静态方法。

 

    1. newMapperProxy

  @SuppressWarnings("unchecked")
public static <T> T newMapperProxy(Class<T> mapperInterface, SqlSession sqlSession) {
    ClassLoader classLoader = mapperInterface.getClassLoader();
    Class<?>[] interfaces = new Class[]{mapperInterface};
    MapperProxy proxy = new MapperProxy(sqlSession);
    return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy);
  }

 newMapperProxy是一个java动态代理,支持泛型。mapperInterface就是自己定义的Mapper接口,SqlSession则从外部生成,传入。以后再学习、研究。现在主要来看MapperProxy.invoke。

 

    2.  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable

 

final Class<?> declaringInterface = findDeclaringInterface(proxy, method);
final MapperMethod mapperMethod = new MapperMethod(declaringInterface, method, sqlSession);
final Object result = mapperMethod.execute(args);

 主要是获得被代理对象的接口,委托org.apache.ibatis.binding.MapperMethod执行,并获得结果。重点转到MapperMethod对象。

 

    3.

 

  public MapperMethod(Class<?> declaringInterface, Method method, SqlSession sqlSession) {
   //........
    this.config = sqlSession.getConfiguration();
 }

 在构造方法里将自定义的Mapper接口的方法(方法定义、传参数、返回值、方法相关的注解)与配置文件(config)关联起来:

 

//代码不连续,只选择部分关键代码
//完整的 类名.方法名 组成commandName
 this.commandName = declaringInterface.getName() + "." + method.getName();
//通过commandName关联配置信息
//type为:public enum SqlCommandType { UNKNOWN, INSERT, UPDATE, DELETE, SELECT; }
MappedStatement ms = config.getMappedStatement(commandName);
 type = ms.getSqlCommandType(); 
//参数的注解信息,顺序
paramName = ((Param) paramAnnos[j]).value();
//返回值信息
 if (List.class.isAssignableFrom(method.getReturnType()))

 在Object execute(Object[] args)方法中根据type调用SqlSession不同的方法

 

  public Object execute(Object[] args) {
    Object result = null;
    if (SqlCommandType.INSERT == type) {
      Object param = getParam(args);
      result = sqlSession.insert(commandName, param);
    }//......
    } else if (SqlCommandType.SELECT == type) {
      if (returnsVoid && resultHandlerIndex != null) {
        executeWithResultHandler(args);//取交集 ???
      } else if (returnsList) {
        result = executeForList(args);//委托sqlSession.selectList
      } else if (returnsMap) {
        result = executeForMap(args);//委托sqlSession.selectMap
      } else {    //可能返回一个自定义的类
        Object param = getParam(args);
        result = sqlSession.selectOne(commandName, param);
      }
    return result;
  }

目前为止,自定义的Mapper接口的使命就完成了,所有的查询都交给SqlSession处理。那么SqlSession怎么生成的,怎么处理即成为了重点。

 

a.连接的生成、结果集的封转。

b.配置文件的解析,动态sql生成、缓存、事务

 

你可能感兴趣的:(mybatis)