StatementHandler#接口列表
//获取Statement对象,供操作数据库
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;
//获取绑定的sql信息,包含sql语句
BoundSql getBoundSql();
//获取参数处理类,处理参数的映射等
ParameterHandler getParameterHandler();
RoutingStatementHandler-代理委托类
其基本是间接类,只是根据statementType类型创建不同的StatementHandler类,达到适配的效果。此处我们只需要观察它的构造函数
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
//根据mappedStatement中的statementType类型来进行委托类的创建
//默认都是PrepareStatementHandler
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());
}
}
mybatis在某语句不指定statementType属性的情况下,默认创建PrepareStatementHandler
BaseStatementHandler-基本抽象实现类
BaseStatementHandler-构造函数
瞧下代码
protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
this.configuration = mappedStatement.getConfiguration();
this.executor = executor;
this.mappedStatement = mappedStatement;
this.rowBounds = rowBounds;
//java类型处理类
this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
this.objectFactory = configuration.getObjectFactory();
//此处兼容doUpdate()方法的调用,因为传过来的boundSql为null
if (boundSql == null) { // issue #435, get the key before calculating the statement
generateKeys(parameterObject);
boundSql = mappedStatement.getBoundSql(parameterObject);
}
this.boundSql = boundSql;
//paramterMap/resultType属性对应的入参集合处理
this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
//resultMap/resultType属性对应的出参集合处理
this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql);
}
BaseStatementHandler#prepare()-创建sql表达式对象statement
具体源码如下
public Statement prepare(Connection connection) throws SQLException {
ErrorContext.instance().sql(boundSql.getSql());
Statement statement = null;
try {
//创建表达式对象,供子类复写
statement = instantiateStatement(connection);
//设置执行sql的超时时间
setStatementTimeout(statement);
//通过mappedStatement对象设置statement的fetchSize大小
setFetchSize(statement);
return statement;
}//出现异常则关闭表达式对象
catch (SQLException e) {
closeStatement(statement);
throw e;
} catch (Exception e) {
closeStatement(statement);
throw new ExecutorException("Error preparing statement. Cause: " + e, e);
}
}
我们以mybatis默认的PrepareStatementHandler
为例
PrepareStatementHandler-预表达式帮助类
PrepareStatementHandler#instantiateStatement()-创建Statement对象
创建的对象为PrepareStatement
,具体源码如下
protected Statement instantiateStatement(Connection connection) throws SQLException {
//获取待执行的sql语句
String sql = boundSql.getSql();
//主键列设置,一般此处针对insert语句
if (mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) {
String[] keyColumnNames = mappedStatement.getKeyColumns();
if (keyColumnNames == null) {
return connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
} else {
return connection.prepareStatement(sql, keyColumnNames);
}
}//ResultSet返回类型,默认为空
else if (mappedStatement.getResultSetType() != null) {
return connection.prepareStatement(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
} else {
return connection.prepareStatement(sql);
}
}
PrepareStatementHandler#update()-CUD操作入口
源码奉上
public int update(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
//对增删改都会返回执行成功的记录数目
int rows = ps.getUpdateCount();
//针对key进行处理
Object parameterObject = boundSql.getParameterObject();
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
return rows;
}
PrepareStatementHandler#query()-R操作入口
源码奉上
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
//对select语句返回的resultMap/resultType进行相应的映射
return resultSetHandler.<E> handleResultSets(ps);
}