由下面这个测试类开始分析其内部运行原理:
[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
|