第三节简单介绍了初始化过程,最终获得了SqlSessionFactory对象,加下来就是执行SQL,就需要SqlSession对象,使用工厂模式从SqlSessionFactory获得SqlSession,这节分析SqlSession如何一步一步执行SQL并返回结果的过程。一样,代码删繁就简,为了方便分析。
1、获得SqlSession
SqlSession sqlSession = factory.openSession();
SqlSession在Mybatis里有两类实现:DefaultSqlSession(默认)和 SqlSessionManager(弃用,不介绍)
public class DefaultSqlSession implements SqlSession {
private final Configuration configuration;
private final Executor executor;
}
两个属性,一个核心配置类Configuration ,一个执行器Executor ,SqlSession 执行SQL下一层就是Executor 来完成。
看下openSession方法
2、openSession()
public class DefaultSqlSessionFactory implements SqlSessionFactory {
@Override
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
}
这里configuration.getDefaultExecutorType()返回的是SIMPLE,就是SimpleExecutor
3、openSessionFromDataSource()
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
}
这里就是生成SimpleExecutor执行器赋值给DefaultSqlSession
public class DefaultSqlSession implements SqlSession {
private final Configuration configuration;
private final Executor executor;
public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
this.configuration = configuration;
this.executor = executor;
this.dirty = false;
this.autoCommit = autoCommit;
}
}
4、获得SqlSession 开始执行SQL
进入selectList的多个重载方法
List<Object> list =sqlSession.selectList("com.mapper.UserMapper.getUserByName");
@Override
public <E> List<E> selectList(String statement) {
return this.selectList(statement, null);
}
@Override
public <E> List<E> selectList(String statement, Object parameter) {
return this.selectList(statement, parameter, RowBounds.DEFAULT);
}
@Override
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
MappedStatement ms = configuration.getMappedStatement(statement);
return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
}
最后一个重载方法,从configuration的Map<String, MappedStatement> mappedStatements中获取MappedStatement ,接下来就是执行器executor执行SQL。
5、executor执行器query()方法
@Override
public
<E
> List
<E
> query
(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler
) throws SQLException
{
//根据入参返回动态SQL
BoundSql boundSql
= ms.getBoundSql
(parameter
);
//本次查询创建缓存
CacheKey key
= createCacheKey
(ms, parameter, rowBounds, boundSql
);
//query重载
return query
(ms, parameter, rowBounds, resultHandler, key, boundSql
);
}
@Override
public
<E
> List
<E
> doQuery
(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql
) throws SQLException
{
Statement stmt
= null
;
Configuration configuration
= ms.getConfiguration
();
StatementHandler handler
= configuration.newStatementHandler
(wrapper, ms, parameter, rowBounds, resultHandler, boundSql
);
stmt
= prepareStatement
(handler, ms.getStatementLog
());
return handler.
<E
>query
(stmt, resultHandler
);
}
SimpleExecutor调用doQuery进行查询,到这里,就要到executor的下一层StatementHandler ,从StatementHandler 中获取Statement ,然后再调用handler.query(stmt, resultHandler);
@Override
public
<E
> List
<E
> query
(Statement statement, ResultHandler resultHandler
) throws SQLException
{
String sql
= boundSql.getSql
();
statement.execute
(sql
);
return resultSetHandler.
<E
>handleResultSets
(statement
);
}
到这里就是JSBC的执行了,最后使用resultSetHandler封装结果集映射