mybatis源码解读:session包

session包是整个mybatis应用的对外接口包。

1.SqlSession及其相关类

1.1 SqlSession的生成链

在进行查询操作时,只需要和SqlSession对象打交道,而SqlSession对象是由SqlSessionFactory生产出来的,而SqlSessionFactory又是由SqlSessionFactoryBuilder创建的。

public class SqlSessionFactoryBuilder {

public SqlSessionFactory build(Reader reader) {
return build(reader, null, null);
}

public SqlSessionFactory build(Reader reader, String environment) {
return build(reader, environment, null);
}

public SqlSessionFactory build(Reader reader, Properties properties) {
return build(reader, null, properties);
}

/**
* 建造一个SqlSessionFactory对象
* @param reader 读取字符流的抽象类
* @param environment 环境信息
* @param properties 配置信息
* @return SqlSessionFactory对象
*/
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
// 传入配置文件,创建一个XMLConfigBuilder类
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
// 分两步:
// 1、解析配置文件,得到配置文件对应的Configuration对象
// 2、根据Configuration对象,获得一个DefaultSqlSessionFactory
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
}
}
}

public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}

public SqlSessionFactory build(InputStream inputStream, String environment) {
return build(inputStream, environment, null);
}

public SqlSessionFactory build(InputStream inputStream, Properties properties) {
return build(inputStream, null, properties);
}

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) {
}
}
}

/**
* 根据配置信息建造一个SqlSessionFactory对象
* @param config 配置信息
* @return SqlSessionFactory对象
*/
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}

}

​DefaultSqlSessionFactory对象可以创建出SqlSession的子类DefualtSqlSession类的对象,该过程由openSessionFromDataSourcce方法完成。

/**
* 从数据源中获取SqlSession对象
* @param execType 执行器类型
* @param level 事务隔离级别
* @param autoCommit 是否自动提交事务
* @return SqlSession对象
*/
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);
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}

至此,整个SqlSession生成链的相关操作,经过逐级生成后终于得到DefaultSqlSession对象。

1.2 DefaultSqlSessio类

public class DefaultSqlSession implements SqlSession {
// 配置信息
private final Configuration configuration;
// 执行器
private final Executor executor;
// 是否自动提交
private final boolean autoCommit;
// 缓存是否已经被污染
private boolean dirty;
// 游标列表
private List<Cursor<?>> cursorList;

/**
* 查询结果列表
* @param <E> 返回的列表元素的类型
* @param statement SQL语句
* @param parameter 参数对象
* @param rowBounds 翻页限制条件
* @return 结果对象列表
*/
@Override
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
try {
// 获取查询语句
MappedStatement ms = configuration.getMappedStatement(statement);
// 交由执行器进行查询
return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
}

DefaultSqlSession类将主要操作都交给属性中的Executor对象处理,相关数据库查询操作都有Executor对象的query方法来完成。

1.3SqlSessionManager类

public class SqlSessionManager implements SqlSessionFactory, SqlSession {

// 构造方法中传入的SqlSessionFactory对象
private final SqlSessionFactory sqlSessionFactory;
// 在构造方法中创建的SqlSession代理对象
private final SqlSession sqlSessionProxy;
// 该变量用来存储被代理的SqlSession对象
private final ThreadLocal<SqlSession> localSqlSession = new ThreadLocal<>();

/**
* SqlSessionManager构造方法
* @param sqlSessionFactory SqlSession工厂
*/
private SqlSessionManager(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
this.sqlSessionProxy = (SqlSession) Proxy.newProxyInstance(
SqlSessionFactory.class.getClassLoader(),
new Class[]{SqlSession.class},
new SqlSessionInterceptor());
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 尝试从当前线程中取出SqlSession对象
final SqlSession sqlSession = SqlSessionManager.this.localSqlSession.get();
if (sqlSession != null) { // 当前线程中确实取出了SqlSession对象
try {
// 使用取出的SqlSession对象进行操作
return method.invoke(sqlSession, args);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
} else { // 当前线程中还没有SqlSession对象
// 使用属性中的SqlSessionFactory对象创建一个SqlSession对象
try (SqlSession autoSqlSession = openSession()) {
try {
// 使用新创建的SqlSession对象进行操作
final Object result = method.invoke(autoSqlSession, args);
autoSqlSession.commit();
return result;
} catch (Throwable t) {
autoSqlSession.rollback();
throw ExceptionUtil.unwrapThrowable(t);
}
}
}
}
}
}