mybatis内部运行原理

由下面这个测试类开始分析其内部运行原理:

public class UserMapperTest {
	@Test
	public void testQueryUserById() throws IOException {
		String resource ="mybatis/mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession sqlSession = sqlSessionFactory.openSession(true);
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		User user = userMapper.queryUserById(1l);
		System.out.println(user);
	}
}

首先是读取mybatis-config.xml配置文件,获取配置文件的输入流,然后通过SqlSessionFactoryBuilder类的build()方法构造。
进入build方法,可以看到通过XMLConfigBuilder解析inputStream中的配置参数,
后用解析到的parser调用parse()方法:parser.parse(),进入parse()方法.

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        inputStream.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }

parser.parse()将配置数据存入Configuration类中,返回configuration
Configuration是一个很关键的类,mybatis中所有配置信息基本都存于此。

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

后执行build(parser.parse()),即SqlSessionFactoryBuilder类的build方法,创建一个DefaultSqlSessionFactory对象,此类是SqlSessionFactory的一个实现类,后得到SqlSessionFactory

public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

接下来就是获取sqlSession了,SqlSession也是一个非常重要的类,通过它去和数据库打交道。我们来看如何获取sqlSession,进入sqlSessionFactory.openSession()方法。最终会来到sqlSessionFactory的实现类DefaultSqlSessionFactory中的方法如下。

public SqlSession openSession(boolean autoCommit) {
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
  }

后进入openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit)方法,如下:

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);
      final Executor executor = configuration.newExecutor(tx, execType);
      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();
    }
  }

可以看到,通过取出configuration对象中的数据源,创建一个执行器Executor,最后通过new DefaultSqlSession(configuration, executor, autoCommit);得到SqlSession。Executor执行器也是一个非常重要的接口,它真正地实现了与数据库的交互。
到此为止,获取到sqlSession对象后,说明已经与数据库真正建立了连接关系,接下来就是实际的交互,发送sql了。
在获取数据之前,我们再看一下源码中对SqlSession类的描述:

The primary Java interface for working with MyBatis. Through this
interface you can execute commands, get mappers and manage
transactions.
SqlSession类是mybatis运行的最核心的java接口,通过这个接口可以执行命令、获取Mapper类、管理事务。

mybatis中Mapper接口如何实例化的(为什么mybatis的mapper没有实现类)

猜你喜欢

转载自blog.csdn.net/qq_42848910/article/details/105664183
今日推荐