MyBatis中StatementHandler
StatementHandler负责操作Statement对象和数据库进行交流,其中还会用到ParameterHandler和ResultSetHandler进行参数的赋值和结果集的映射
1.StatementHandler中主要的方法
Statement prepare(Connection connection)throws SQLException;
void parameterize(Statement statement)throws SQLException;
int update(Statement statement) throws SQLException;
List query(Statement statement,ResultHandler resultHandler)throws SQLException;
prepare: 用于创建一个Statement实例
parametersize: 用于初始化Statement对象以及对sql的占位符进行赋值
update: 用于通知Statement对象将 insert、update、delete 操作推送到数据库
query: 用于通知Statement对象将 select 操作推送数据库并返回对应的查询结果
2.StatementHandler的继承机构
文章图片
StatementHandler的两个实现类
BaseStatementHandler:抽象类,提供了一些公共的实现,简化StatementHandler接口的实现难度
RoutingStatementHandler:StatementHandler接口的默认实现, 根据StatementType获取到真正的StatementHandler,然后赋值给属性delegate
文章图片
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {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的三个实现类:
SimpleStatementHandler:处理不需要预编译的sql,不需要处理参数的sql
PreparedStatementHandler:处理需要预编译的sql
CallableStatementHandler:调用存储过程
在查询和更新时才会去获取StatementHandler对象,因此它是由Executor管理和创建的。
以SimpleExecutor为例分析生成StatementHandler和Statement的源码
public List 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);
//获取Statement对象
** stmt = prepareStatement(handler, ms.getStatementLog());
**
return handler.query(stmt, resultHandler);
} finally {
closeStatement(stmt);
}
}
【MyBatis中StatementHandler】获取Statement实例源码分析
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
Statement stmt;
Connection connection = getConnection(statementLog);
//获取Statement实例
stmt = handler.prepare(connection, transaction.getTimeout());
//stmt进行参数处理
//SimpleStatementHandler中parameterize为空方法,因为它只处理简单sql,有参数的sql由
PreparedStatementHandler处理
handler.parameterize(stmt);
return stmt;
}
//调用RoutingStatementHandler中的方法,实质是调用了属性delegate的prepare方法
//上面提到了delegate的赋值
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
return delegate.prepare(connection, transactionTimeout);
} //调用BaseStatementHandler中的prepare
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
ErrorContext.instance().sql(boundSql.getSql());
Statement statement = null;
try {
//由子类提供实现
statement = instantiateStatement(connection);
setStatementTimeout(statement, transactionTimeout);
setFetchSize(statement);
return statement;
} //SimpleStatementHandler提供的实现
protected Statement instantiateStatement(Connection connection) throws SQLException {
if (mappedStatement.getResultSetType() = null) {
return connection.createStatement(mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
} else {
return connection.createStatement();
}
}
推荐阅读
- 热闹中的孤独
- Shell-Bash变量与运算符
- JS中的各种宽高度定义及其应用
- 2021-02-17|2021-02-17 小儿按摩膻中穴-舒缓咳嗽
- 深入理解Go之generate
- 异地恋中,逐渐适应一个人到底意味着什么()
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- “成长”读书社群招募
- 2020-04-07vue中Axios的封装和API接口的管理