源码分析----Mybatis

一、源码分析

1、创建会话工厂

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

·1.1 调用了parse方法,将mybatis配置文件的信息全部解析到一个Configuration对象中(包扩mybatis启动配置信息,数据源,Mapper.xml(sql语句))

  public Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

1.1.1 解析Mapper.xml

private void mapperElement(XNode parent) throws Exception {
    if (parent != null) {
      for (XNode child : parent.getChildren()) {
        if ("package".equals(child.getName())) {
          String mapperPackage = child.getStringAttribute("name");
          configuration.addMappers(mapperPackage);
        } else {
          String resource = child.getStringAttribute("resource");
          String url = child.getStringAttribute("url");
          String mapperClass = child.getStringAttribute("class");
          if (resource != null && url == null && mapperClass == null) {
            ErrorContext.instance().resource(resource);
            InputStream inputStream = Resources.getResourceAsStream(resource);
            XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
            mapperParser.parse();
          } else if (resource == null && url != null && mapperClass == null) {
            ErrorContext.instance().resource(url);
            InputStream inputStream = Resources.getUrlAsStream(url);
            XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());

           //将解析mybatis配置中的mapper节点,里面将解析mapper.xml中的sql
            mapperParser.parse();
          } else if (resource == null && url == null && mapperClass != null) {
            Class<?> mapperInterface = Resources.classForName(mapperClass);
            configuration.addMapper(mapperInterface);
          } else {
            throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
          }
        }
      }
    }
  }

1.1.1.1 里面执行了(将sql信息封装到了MapperedStatement中(一个MapperedStatement代表了增删改查的详细信息),MappedStatement封装在了Configuration对象中)

builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
        fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
        resultSetTypeEnum, flushCache, useCache, resultOrdered, 
        keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);

 

第一步结束后,最终返回一个 DefaultSqlSessionFactory(保存了Configuration,里面最重要的两个属性

public class Configuration {
    protected MapperRegistry mapperRegistry = new MapperRegistry(this); //用于生产mapper代理
    protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>("Mapped Statements collection"); 
}

  

2、通过工厂得到SqlSession

SqlSession sqlSession = sqlSessionFactory.openSession();  

2.1

return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);

2.1.1 返回一个 defaultExecutorType = ExecutorType.SIMPLE(默认),还要其他的(BATCH,REUSE),后面会根据这个创建不同的 Executor

configuration.getDefaultExecutorType()

2.1.2

  private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
    //获取环境信息
      final Environment environment = configuration.getEnvironment();
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      
    //创建4大对象之一的Executor
    final Executor executor = configuration.newExecutor(tx, execType);
    
    //返回DefaultSqlSession(里面包含配置信息,和执行器)
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      closeTransaction(tx); // may have fetched a connection so lets call close()
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

2.1.2.1 根据 ExecutorType,创建不同的执行器,Executor是一个接口,规定了增删改查的所有的方法;

public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    if (ExecutorType.BATCH == executorType) {
      executor = new BatchExecutor(this, transaction);
    } else if (ExecutorType.REUSE == executorType) {
      executor = new ReuseExecutor(this, transaction);
    } else {
      executor = new SimpleExecutor(this, transaction);
    }
  //是否配置了二级缓存
    if (cacheEnabled) {
      executor = new CachingExecutor(executor);
    }

    //执行拦截器链(interceptorChain封装了拦截器列表),非常重要,每一个executory的创建都要被拦截
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }  

2.1.2.1.1

  private final List<Interceptor> interceptors = new ArrayList<Interceptor>();

  public Object pluginAll(Object target) {
    for (Interceptor interceptor : interceptors) {
      target = interceptor.plugin(target); //执行每一个拦截器的plugin方法,如果没有就跳过
    }
    return target;
  }

第2步主要就是返回了一个 DefaultSqlSession,里面创建了执行器,封装到DefaultSqlSession中

 

3、获取代理对象,代理对象去执行增删改查

UserDao mapper = sqlSession.getMapper(UserDao.class);

3.1

  public <T> T getMapper(Class<T> type) {
    return configuration.<T>getMapper(type, this);
  }

3.1.1

  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    return mapperRegistry.getMapper(type, sqlSession);
  }

3.1.1.1

  @SuppressWarnings("unchecked")
  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
  //knownMappers通过type,获得代理对象
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
    if (mapperProxyFactory == null)
      throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
    try {
      return mapperProxyFactory.newInstance(sqlSession);
    } catch (Exception e) {
      throw new BindingException("Error getting mapper instance. Cause: " + e, e);
    }
  }

3.1.1.1.1

mapperProxyFactory.newInstance(sqlSession);

3.1.1.1.1.1 public class MapperProxy<T> implements InvocationHandler, Serializable (MapperProxy就是一个InvocationHander)

  public T newInstance(SqlSession sqlSession) {
    final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

3.1.1.1.1.1.1 最终创建代理

  protected T newInstance(MapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

  

  

 

posted @ 2019-08-09 21:36  小名的同学  阅读(134)  评论(0编辑  收藏  举报