而本文解析的类,都在 session 包下,整体类图如下:
老艿艿:省略了一部分前面已经解析过的类。

- 核心是 SqlSession 。
- SqlSessionFactory ,负责创建 SqlSession 对象的工厂。
- SqlSessionFactoryBuilder ,是 SqlSessionFactory 的构建器。
下面,我们按照 SqlSessionFactoryBuilder => SqlSessionFactory => SqlSession 来详细解析。
2. SqlSessionFactoryBuilder
org.apache.ibatis.session.SqlSessionFactoryBuilder ,SqlSessionFactory 构造器。代码如下:
// SqlSessionFactory.java
|
- 提供了各种 build 的重载方法,核心的套路都是解析出 Configuration 配置对象,从而创建出 DefaultSqlSessionFactory 对象。
3. SqlSessionFactory
org.apache.ibatis.session.SqlSessionFactory ,SqlSession 工厂接口。代码如下:
// SqlSessionFactory.java
|
- 定义了
#openSession(...)和#getConfiguration()两类方法。
3.1 DefaultSqlSessionFactory
org.apache.ibatis.session.defaults.DefaultSqlSessionFactory ,实现 SqlSessionFactory 接口,默认的 SqlSessionFactory 实现类。
3.1.1 构造方法
// DefaultSqlSessionFactory.java
|
3.1.2 openSession
// DefaultSqlSessionFactory.java
|
-
调用
#openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit)方法,获得 SqlSession 对象。代码如下:// DefaultSqlSessionFactory.java
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
// 获得 Environment 对象
final Environment environment = configuration.getEnvironment();
// 创建 Transaction 对象
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
// 创建 Executor 对象
final Executor executor = configuration.newExecutor(tx, execType);
// 创建 DefaultSqlSession 对象
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
// 如果发生异常,则关闭 Transaction 对象
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}- DefaultSqlSession 的创建,需要
configuration、executor、autoCommit三个参数。
- DefaultSqlSession 的创建,需要
-
#openSessionFromConnection(ExecutorType execType, Connection connection)方法,获得 SqlSession 对象。代码如下:// DefaultSqlSessionFactory.java
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;
}
// 获得 Environment 对象
final Environment environment = configuration.getEnvironment();
// 创建 Transaction 对象
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
final Transaction tx = transactionFactory.newTransaction(connection);
// 创建 Executor 对象
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();
}
}
3.1.3 getTransactionFactoryFromEnvironment
// DefaultSqlSessionFactory.java
|
3.1.4 closeTransaction
// DefaultSqlSessionFactory.java
|
4. SqlSession
org.apache.ibatis.session.SqlSession ,SQL Session 接口。代码如下:
// SqlSession.java
|
- 大体接口上,和 Executor 接口是相似的。
4.1 DefaultSqlSession
org.apache.ibatis.session.defaults.DefaultSqlSession ,实现 SqlSession 接口,默认的 SqlSession 实现类。
4.1.1 构造方法
// DefaultSqlSession.java
|
4.1.2 selectList
// DefaultSqlSession.java
|
-
<1>处,调用Configuration#getMappedStatement(String id)方法,获得 MappedStatement 对象。代码如下:// DefaultSqlSession.java
/**
* MappedStatement 映射
*
* KEY:`${namespace}.${id}`
*/
protected final Map<String, MappedStatement> mappedStatements = new StrictMap<>("Mapped Statements collection");
public MappedStatement getMappedStatement(String id, boolean validateIncompleteStatements) {
// 校验,保证所有 MappedStatement 已经构造完毕
if (validateIncompleteStatements) {
buildAllStatements();
}
// 获取 MappedStatement 对象
return mappedStatements.get(id);
}
protected void buildAllStatements() {
if (!incompleteResultMaps.isEmpty()) {
synchronized (incompleteResultMaps) { // 保证 incompleteResultMaps 被解析完
// This always throws a BuilderException.
incompleteResultMaps.iterator().next().resolve();
}
}
if (!incompleteCacheRefs.isEmpty()) {
synchronized (incompleteCacheRefs) { // 保证 incompleteCacheRefs 被解析完
// This always throws a BuilderException.
incompleteCacheRefs.iterator().next().resolveCacheRef();
}
}
if (!incompleteStatements.isEmpty()) {
synchronized (incompleteStatements) { // 保证 incompleteStatements 被解析完
// This always throws a BuilderException.
incompleteStatements.iterator().next().parseStatementNode();
}
}
if (!incompleteMethods.isEmpty()) {
synchronized (incompleteMethods) { // 保证 incompleteMethods 被解析完
// This always throws a BuilderException.
incompleteMethods.iterator().next().resolve();
}
}
}- 其中,
#buildAllStatements()方法,是用来保证所有 MappedStatement 已经构造完毕。不过艿艿,暂时没想到,什么情况下,会出现 MappedStatement 没被正确构建的情况。猜测有可能是防御性编程。
- 其中,
<2>处,调用Executor#query(...)方法,执行查询。
4.1.3 selectOne
// DefaultSqlSession.java
|
- 内部调用
#selectList(String statement, Object parameter)方法,进行实现。
4.1.4 selectMap
#selectMap(...) 方法,查询结果,并基于 Map 聚合结果。代码如下:
// DefaultSqlSession.java
|
<1>处,调用#selectList(String statement, Object parameter, RowBounds rowBounds)方法,执行查询。<2>处,创建 DefaultMapResultHandler 对象。<3>处,创建 DefaultResultContext 对象。-
<4>处,遍历查询结果,并调用DefaultMapResultHandler#handleResult(context)方法,将结果的当前元素,聚合成 Map 。代码如下:// DefaultMapResultHandler.java
public class DefaultMapResultHandler<K, V> implements ResultHandler<V> {
/**
* 结果,基于 Map 聚合
*/
private final Map<K, V> mappedResults;
/**
* {@link #mappedResults} 的 KEY 属性名
*/
private final String mapKey;
private final ObjectFactory objectFactory;
private final ObjectWrapperFactory objectWrapperFactory;
private final ReflectorFactory reflectorFactory;
-
<5>处,返回结果。
4.1.5 selectCursor
// DefaultSqlSession.java
|
<1>处,调用Configuration#getMappedStatement(String id)方法,获得 MappedStatement 对象。<2>处,调用Executor#queryCursor(...)方法,执行查询。-
<3>处,调用#registerCursor(Cursor<T> cursor)方法,添加cursor到cursorList中。代码如下:// DefaultSqlSession.java
private <T> void registerCursor(Cursor<T> cursor) {
if (cursorList == null) {
cursorList = new ArrayList<>();
}
cursorList.add(cursor);
}
4.1.6 select
#select(..., ResultHandler handler) 方法,执行查询,使用传入的 handler 方法参数,对结果进行处理。代码如下:
// DefaultSqlSession.java
|
4.1.7 wrapCollection
在上述的查询方法中,我们都可以看到一个 #wrapCollection(final Object object) 方法,若参数 object 是 Collection、Array、Map 参数类型的情况下,包装成 Map 返回。代码如下:
// DefaultSqlSession.java
|
4.1.8 update
// DefaultSqlSession.java |