黑马程序员技术交流社区

标题: 【西安校区】mybatis内部运行原理 [打印本页]

作者: 逆风TO    时间: 2020-4-22 10:27
标题: 【西安校区】mybatis内部运行原理
由下面这个测试类开始分析其内部运行原理:
[Java] 纯文本查看 复制代码
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()方法.
[JavaScript] 纯文本查看 复制代码
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
Congifutation是一个很关键的类,mybatis中所有配置信息基本都存于此。
[Java] 纯文本查看 复制代码
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
[Java] 纯文本查看 复制代码
public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

接下来就是获取sqlSession了,SqlSession也是一个非常重要的类,通过它去和数据库打交道。我们来看如何获取sqlSession,进入sqlSessionFactory.openSession()方法。最终会来到sqlSessionFactory的实现类DefaultSqlSessionFactory中的方法如下。
[JavaScript] 纯文本查看 复制代码
public SqlSession openSession(boolean autoCommit) {
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
  }


后进入openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit)方法,如下:
[Java] 纯文本查看 复制代码
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类、管理事务。
————————————————
转自https://blog.csdn.net/qq_42848910/article/details/105664183






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2