mybatis源码分析——Executor的用法
Executor在mybatis中主要是用来执行jdbc操作的,分为几个类型SimpleExecutor,batchExecutor,SqlSession类维护Executor,
在SqlSession需要操作数据库时,会委托给executor执行,下面通过源码分析一下:
看一下DefaultSqlSession类,里面维护了Executor属性,
当sqlSession调用selectList方法时,会委托给executor处理,executor.query
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(); } }
executor调用query,到baseExecutor,然后通过钩子方法,会调用doQuery,doQuery的逻辑就是jdbc操作数据库了
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { Statement stmt = null; try { 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); } finally { closeStatement(stmt); } }
看一下prepareStatement方法,首先获取连接connection,然后通过连接获取statement,然后将参数设置进去,返回statement
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException { Statement stmt; Connection connection = getConnection(statementLog); stmt = handler.prepare(connection); handler.parameterize(stmt); return stmt; }
看一下statementHandler的query方法,在上一步中已经将statement封装好,在这里执行execute,然后通过resultSetHandler取回结果返回
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException { PreparedStatement ps = (PreparedStatement) statement; ps.execute(); return resultSetHandler.<E> handleResultSets(ps); }
总结:
代码的整体框架很清晰,Executor的作用就是接受SqlSession的委托,然后执行jdbc的操作,当然它对于jdbc的操作又进行了封装
主要通过StatementHandler、resultSetHandler、parameterHandler三个类进行封装
statementHandler负责获取statement、参数化、执行查询
public interface StatementHandler { Statement prepare(Connection connection) throws SQLException; void parameterize(Statement statement) throws SQLException; void batch(Statement statement) throws SQLException; int update(Statement statement) throws SQLException; <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException; BoundSql getBoundSql(); ParameterHandler getParameterHandler(); }
resultSetHandler负责将执行结果转换为model
parameterHandler负责将sql占位符替换为参数值