MyBatis源码学习笔记(二)
参考文档中介绍Mybatis的中心是SqlSessionFactory.并举出一个简单的生成方法:
String resource = “org/mybatis/example/mybatis-config.xml”;
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().bulid(inputStream);
文档列举的基本xml如下:

configuration
关注到基本xml中,根节点为configuration,里面有两个子节点environments, mappers.
由此我想到几个点:
(1) SqlSessionFactory的作用
(2) SqlSessionFactoryBuilder类(这里应该是使用了Builder模式,mybatis中大量使用了builder模式。)
(3) 还有就是基本xml中最低限度的配置项。
查看SqlSessionFactory的代码

SqlSessionFactory
接口中一共有8个openSession方法,
一个无参,一个参数是是否自动提交,一个是根据Connection打开session,一个是TransactionIsolationLevel 是一个枚举类型,代码如下:

TransactionIsolationLevel
是对connection中事务等级的封装。
还有的4个是与此对应的,增加了ExecutorType(枚举类型)的openSession
public enum ExecutorType {
SIMPLE, REUSE, BATCH
}
Executor Type代表执行类型,暂时看来只有简单,重用,批处理。
代码看到这里,还是对这个执行类型没有概念,这个问题可能要留到后面再解决。
在这里SqlSessionFactory提供获取Session的方法,而且代码中跟Configuration有耦合,SqlSessionFactory可能可以透过Configuration,调整配置。
接下来看一看SqlSessionFacoty中的方法
SqlSessionFactort中的build方式,其实只有三个
一个是
public SqlSessionFactory build(Reader reader, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { reader.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } }
另一个是
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. } } }
还有就是
public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }
其他方法只是对build(InputStream inputStream, String environment, Properties properties),build(Reader reader, String environment, Properties properties)修改为null参数的引用,两个build方法针对InputStream,Reader。在这两个方法中,最后调用的都是
build(parser.parse());
所以其实关键的最后方法都是利用Configuration,生成一个DefaultSqlSessionFactory。
这里就清晰了SessionFactoryBuilder生成SqlSessionFactory的方式了。
SessionFactory是一个接口,实现类为
就是我们刚才的DefaultSqlSessionFactory,还有一个新出现的SqlSessionManager。
DefaultSqlSessionFactory中除了实现SqlSessionFactory的方法外,还增加了几个私有的方法。暂时我只关注其中的
public DefaultSqlSessionFactory(Configuration configuration) { this.configuration = configuration; }
DefaultSqlSessionFactory中没有空的构造方法,只提供Configuration为参数的构造方法,避免了空参构造脱离了configuration。
public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); }
configuration.getDefaultExecutorType()就是刚才ExecutorType 中的simple简单类型。
最简单的无参openSession,调用了openSessionFromDataSource方法。
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, autoCommit); return new DefaultSqlSession(configuration, executor); } 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(); } }
暂时就先学习到这里,估计下面就会慢慢接近参考文档提供出来的最基本配置,还有就是,我刚才还不是很明白的ExecutorType的执行类型了。