文章目录
- 1.StatementHandler
- 1.1 StatementHandler 的继承关系
- 1.2 StatementHandler 的创建
- 2.Sql执行流程分析
- 3.ParameterHandler
- 3.1 PreparedStatement的继承体系
- 3.2 ParameterHandler对象创建
- 3.3 PrepareStatment的参数赋值
- 4.ResultSetHandler
- 4.1 ResultSetHandler继承体系
1.StatementHandler
Statementhandler是四大神器中最重要的一个对象,负责操作Statement与数据库进行交流.在工作时还会使用ParameterHandler进行参数配置,使用ResultHandler将查询结果与实体类对象进行绑定我们使用原生jdbc的时候会有statement相关的操作 。
Statement stmt = conn.createStatement();
public interface StatementHandler {
Statement prepare(Connection var1, Integer var2) throws SQLException;
void parameterize(Statement var1) throws SQLException;
void batch(Statement var1) throws SQLException;
int update(Statement var1) throws SQLException;
<E> List<E> query(Statement var1, ResultHandler var2) throws SQLException;
<E> Cursor<E> queryCursor(Statement var1) throws SQLException;
BoundSql getBoundSql();
ParameterHandler getParameterHandler();
}
- prepare: 用于创建一个具体的 Statement 对象的实现类或者是 Statement 对象
- parametersize: 用于初始化 Statement 对象以及对sql的占位符进行赋值
- update: 用于通知 Statement 对象将 insert、update、delete 操作推送到数据库
- query: 用于通知 Statement 对象将 select 操作推送数据库并返回对应的查询结果
1.1 StatementHandler 的继承关系
StatementHandler是顶级的接口,下面有两个直接实现类
- RoutingStatementHandler: .在这个类中并没有对Statement对象进行具体使用.只是根据得到Executor类型,决定创建何种类型StatementHandler对象。
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
// 根据 statementType 创建对应的 Statement 对象
switch (ms.getStatementType()) {
case STATEMENT:
delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case PREPARED:
delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case CALLABLE:
delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
default:
throw new ExecutorException("Unknown statement type: " + ms.getStatementType());
}
}
BaseStatementHandler: 本身是一个抽象类.用于简化StatementHandler接口实现的难度,属于适配器设计模式体现.它有三个实现类
.
SimpleStatementHandler
,PreparedStatementHandler
,CallableStatementHandler
.-
SimpleStatementHandler
:管理Statement对象向数据库中推送不需要预编译的SQL语句 -
PreparedStatementHandler
:管理PreparedStatementHandler对象向数据库推送预编译的SQL语句 -
CallableStatementHandler
:管理CallableStatement对象调用数据库中构造函数
1.2 StatementHandler 的创建
StatementHandler对象是在SqlSession对象接收到操作命令时,由Configuraion中newStatementHandler方法负责调用的; Configuration 中的 newStatementHandler 是由执行器中的查询、更新方法来提供的,StatementHandler 其实就是由 Executor
负责管理和创建的
SimpleExecutor#doQuery()
Configuration#newStatementHandler()
由上图可以看出RoutingStatementHandler构造方法,将会根据Executor的类型决定创建SimpleStatementHandler,PreparedStatementHandler,CallableStatementHandler实例对象
2.Sql执行流程分析
SimpleExecutor#prepareStatement()
PrepareStatmentHandler#parameterize()
PrepareStatementHandler#query()
从上面的关系可知:
StatmentHandler -> ParameterHandler -> 数据库交互 -> 返回参数给ResultSetHandler
3.ParameterHandler
ParameterHandler顾名思义是mybatis中的参数处理器,负责为 PreparedStatement 的 sql 语句参数动态赋值
public interface ParameterHandler {
//读取参数
Object getParameterObject();
//用于对PreparedStatement的参数赋值.
void setParameters(PreparedStatement var1) throws SQLException;
}
3.1 PreparedStatement的继承体系
只有一个实现类DefaultParameterHandler
3.2 ParameterHandler对象创建
参数处理器对象是在创建StatementHandler对象同时被创建的.由Configuration对象负责创建.
创建时 传入三个对象:执行SQL对应的配置信息
- MappedStatement
- 参数对象Object
- SQL的BoundSql
一个BoundSql对象,代表了一次sql语句的实际执行,而SqlSource对象的责任,就是根据传入的参数对象,动态计算出这个BoundSql,也就是说Mapper文件中的节点的计算,是由SqlSource对象完成的。SqlSource最常用的实现类是DynamicSqlSource
- 这里的MappedStatement 为当初解析xml文件的时候最后的mapper对应的数据。
- 参数对象为传入的参数#{}
- Sql的BoundSql为动态Sql
3.3 PrepareStatment的参数赋值
public void setParameters(PreparedStatement ps) {
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
if (parameterMappings != null) {
for (int i = 0; i < parameterMappings.size(); i++) {
ParameterMapping parameterMapping = parameterMappings.get(i);
if (parameterMapping.getMode() != ParameterMode.OUT) {
Object value;
String propertyName = parameterMapping.getProperty();
if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
value = boundSql.getAdditionalParameter(propertyName);
} else if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;
} else {
MetaObject metaObject = configuration.newMetaObject(parameterObject);
value = metaObject.getValue(propertyName);
}
TypeHandler typeHandler = parameterMapping.getTypeHandler();
JdbcType jdbcType = parameterMapping.getJdbcType();
if (value == null && jdbcType == null) {
jdbcType = configuration.getJdbcTypeForNull();
}
try {
typeHandler.setParameter(ps, i + 1, value, jdbcType);
} catch (TypeException | SQLException e) {
throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
}
}
}
}
}
4.ResultSetHandler
处理Statement执行后产生的结果集,生成结果列表
处理存储过程执行后的输出参数
public interface ResultSetHandler {
<E> List<E> handleResultSets(Statement var1) throws SQLException;
<E> Cursor<E> handleCursorResultSets(Statement var1) throws SQLException;
void handleOutputParameters(CallableStatement var1) throws SQLException;
}
4.1 ResultSetHandler继承体系
只有一个实现类DefaultResultSetHandler
DefaultResultSetHandler 具体的操作就是将Statement执行后的结果集,按照Mapper文件中配置的ResultType或ResultMap来封装成对应的对象,最后将封装的对象返回
public List<Object> handleResultSets(Statement stmt) throws SQLException {
ErrorContext.instance().activity("handling results").object(mappedStatement.getId());
final List<Object> multipleResults = new ArrayList<Object>();
int resultSetCount = 0;
// 第一个结果集
ResultSetWrapper rsw = getFirstResultSet(stmt);
// 获取结果映射resultMap
List<ResultMap> resultMaps = mappedStatement.getResultMaps();
int resultMapCount = resultMaps.size();
// 判断结果映射的数量
validateResultMapsCount(rsw, resultMapCount);
// 处理第一个结果集
while (rsw != null && resultMapCount > resultSetCount) {
ResultMap resultMap = resultMaps.get(resultSetCount);
// 将结果集映射为对应的 ResultMap 对象
handleResultSet(rsw, resultMap, multipleResults, null);
rsw = getNextResultSet(stmt);
cleanUpAfterHandlingResultSet();
resultSetCount++;
}
String[] resultSets = mappedStatement.getResultSets();
if (resultSets != null) {
// 多个结果集
while (rsw != null && resultSetCount < resultSets.length) {
ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]);
if (parentMapping != null) {
String nestedResultMapId = parentMapping.getNestedResultMapId();
ResultMap resultMap = configuration.getResultMap(nestedResultMapId);
handleResultSet(rsw, resultMap, null, parentMapping);
}
rsw = getNextResultSet(stmt);
cleanUpAfterHandlingResultSet();
resultSetCount++;
}
}
return collapseSingleResultList(multipleResults);
}