MyBatis源码的注释不多,不过SqlSession倒是给了两行注释:
/**
* The primary Java interface for working with MyBatis.
* Through this interface you can execute commands, get mappers and manage transactions.
* @author Clinton Begin
*/
public interface SqlSession extends Closeable {}
第一行注释告诉我们SqlSession是使用MyBatis的主要接口,SqlSession有一个默认的实现类DefaultSqlSession,另外一个实现类SqlSessionManager(通过实现接口SqlSessionFactory,增加了工厂的能力)在后面的博文中会有详细的分析。
再看SqlSessionFactory只给了一行注释:
/**
* Creates an {@link SqlSession} out of a connection or a DataSource
* @author Clinton Begin
*/
public interface SqlSessionFactory {}
注释告诉我们,接口SqlSessionFactory用于从数据源或数据库连接中创建SqlSession,SqlSessionFactory也有一个默认的实现类DefaultSqlSessionFactory,另外一个实现类SqlSessionManager,再次不做赘述。
下面看DefaultSqlSessionFacotry中实际产生SqlSession对象的两个方法(从数据源和数据库连接中获取):
// 从数据源中打开Session
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);
// 实际返回的是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();
}
}
// 从数据库连接中打开Session
private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
try {
boolean autoCommit;
try {
autoCommit = connection.getAutoCommit();
} catch (SQLException e) {
// Failover to true, as most poor drivers
// or databases won't support transactions
autoCommit = true;
}
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
final Transaction tx = transactionFactory.newTransaction(connection);
final Executor executor = configuration.newExecutor(tx, execType);
// 实际返回的是DefaultSqlSession
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
从上面的代码得知,实际由DefaultSqlSessionFactory生产DefaultSqlSession对象。
通过上面的分析,可以看出SqlSession和SqlSessionFactory这两个接口,及DefaultSqlSession和DefaultSqlSessionFactory这两个默认实现类,就是典型的抽象工厂模式的实现。
上面讲述了SqlSession的实现类的产生过程,那么SqlSessionFactory是怎么产生的呢?
SqlSessionFactory是由SqlSessionFactoryBuilder产生的,代码如下:
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
DefaultSqlSessionFactory的构造器需要传入MyBatis核心配置类Configuration的对象作为参数,而Configuration庞大且复杂,初始化比较麻烦,使用了专门的建造者XMLConfigBuilder进行构建。
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
// 创建建造者XMLConfigBuilder实例
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
// XMLConfigBuilder的parse()构建Configuration实例
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.
}
}
}
XMLConfigBuilder负责Configuration实例各个组件的创建和装配,整个装配的流程化过程如下:
private void parseConfiguration(XNode root) {
try {
//issue #117 read properties first
// Configuration#
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
reflectorFactoryElement(root.evalNode("reflectorFactory"));
settingsElement(settings);
// read it after objectFactory and objectWrapperFactory issue #631
environmentsElement(root.evalNode("environments"));
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
typeHandlerElement(root.evalNode("typeHandlers"));
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}
XMLConfigBuilder负责创建复杂对象Configuration,SqlSessionFactoryBuilder只不过是做了一层封装去构建SqlSessionFactory实例,这是建造者模式的简化构建过程。