StatementHandle

类图

各个实现类的作用

SimpleStatementHandler 用于使用Statement操作数据库(不会使用参数化查询?)

PreparedStatementHandler 用于使用PreparedStatement操作数据库(会使用参数化查询)

CallableStatementHandler 用于使用CallableStatement 操作数据库(主要是执行存储过程)

RoutingStatementHandler 待定

StatementHandler调用时机

Executor部分代码

 public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
Statement stmt = null; int var6;
try {
Configuration configuration = ms.getConfiguration();
//获得对应的statementHandler 可以是SimpleStatementHandler PreparedStatementHandler CallableStatementHandler
StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, (ResultHandler)null, (BoundSql)null);
//通过StaementHandler设置参数
stmt = this.prepareStatement(handler, ms.getStatementLog());
//调用update方法获得返回结果 内部使用Statement操作数据库
var6 = handler.update(stmt);
} finally {
this.closeStatement(stmt);
} return var6;
}

SimpleStatementHandler

public class SimpleStatementHandler extends BaseStatementHandler {
public SimpleStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
} /**
* 通过Staement执行修改
* @param statement
* @return
* @throws SQLException
*/
public int update(Statement statement) throws SQLException {
//获得sql语句 boundSql接口 根据MapperStatement获得
String sql = this.boundSql.getSql();
Object parameterObject = this.boundSql.getParameterObject();
KeyGenerator keyGenerator = this.mappedStatement.getKeyGenerator();
int rows;
if (keyGenerator instanceof Jdbc3KeyGenerator) {
statement.execute(sql, 1);
rows = statement.getUpdateCount();
keyGenerator.processAfter(this.executor, this.mappedStatement, statement, parameterObject);
} else if (keyGenerator instanceof SelectKeyGenerator) {
statement.execute(sql);
rows = statement.getUpdateCount();
keyGenerator.processAfter(this.executor, this.mappedStatement, statement, parameterObject);
} else {
statement.execute(sql);
rows = statement.getUpdateCount();
} return rows;
} public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {
String sql = this.boundSql.getSql();
statement.execute(sql);
return this.resultSetHandler.handleCursorResultSets(statement);
}
//根据connection创建Statement
protected Statement instantiateStatement(Connection connection) throws SQLException {
return this.mappedStatement.getResultSetType() != null ? connection.createStatement(this.mappedStatement.getResultSetType().getValue(), 1007) : connection.createStatement();
}
//设置参数 由于Staement不支持?参数化查询 sql语句写死参数 所以实现是空的
public void parameterize(Statement statement) throws SQLException {
}
}

PreparedStatementHandler

public class PreparedStatementHandler extends BaseStatementHandler {
public PreparedStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
} public int update(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement)statement;
ps.execute();
int rows = ps.getUpdateCount();
Object parameterObject = this.boundSql.getParameterObject();
KeyGenerator keyGenerator = this.mappedStatement.getKeyGenerator();
keyGenerator.processAfter(this.executor, this.mappedStatement, ps, parameterObject);
return rows;
}
//根据connection创建PrepareStatement
protected Statement instantiateStatement(Connection connection) throws SQLException {
String sql = this.boundSql.getSql();
if (this.mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) {
String[] keyColumnNames = this.mappedStatement.getKeyColumns();
return keyColumnNames == null ? connection.prepareStatement(sql, 1) : connection.prepareStatement(sql, keyColumnNames);
} else {
return this.mappedStatement.getResultSetType() != null ? connection.prepareStatement(sql, this.mappedStatement.getResultSetType().getValue(), 1007) : connection.prepareStatement(sql);
}
}
//设置参数
public void parameterize(Statement statement) throws SQLException {
//交给parameterHandler处理parameterHandler是根据MappedStatement中获得
this.parameterHandler.setParameters((PreparedStatement)statement);
}
}

参数设置是委托给ParameterHandler处理的

CallableStatementHandler

public class CallableStatementHandler extends BaseStatementHandler {
public CallableStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
} public int update(Statement statement) throws SQLException {
CallableStatement cs = (CallableStatement)statement;
cs.execute();
int rows = cs.getUpdateCount();
Object parameterObject = this.boundSql.getParameterObject();
KeyGenerator keyGenerator = this.mappedStatement.getKeyGenerator();
keyGenerator.processAfter(this.executor, this.mappedStatement, cs, parameterObject);
this.resultSetHandler.handleOutputParameters(cs);
return rows;
}
//根据连接创建 CallStatement
protected Statement instantiateStatement(Connection connection) throws SQLException {
String sql = this.boundSql.getSql();
return this.mappedStatement.getResultSetType() != null ? connection.prepareCall(sql, this.mappedStatement.getResultSetType().getValue(), 1007) : connection.prepareCall(sql);
}
//设置参数
public void parameterize(Statement statement) throws SQLException {
this.registerOutputParameters((CallableStatement)statement);
this.parameterHandler.setParameters((CallableStatement)statement);
}
}

ParameterHandler

类图

DefaultParameterHandler

public class DefaultParameterHandler implements ParameterHandler {
private final TypeHandlerRegistry typeHandlerRegistry;
private final MappedStatement mappedStatement;
private final Object parameterObject;
private BoundSql boundSql;
private Configuration configuration; public DefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
this.mappedStatement = mappedStatement;
this.configuration = mappedStatement.getConfiguration();
this.typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();
this.parameterObject = parameterObject;
this.boundSql = boundSql;
} public Object getParameterObject() {
return this.parameterObject;
} public void setParameters(PreparedStatement ps) {
ErrorContext.instance().activity("setting parameters").object(this.mappedStatement.getParameterMap().getId());
//获得BoundSql里面的ParameterMapping 内部保存的是参数的映射
List<ParameterMapping> parameterMappings = this.boundSql.getParameterMappings();
if (parameterMappings != null) {
for(int i = 0; i < parameterMappings.size(); ++i) {
ParameterMapping parameterMapping = (ParameterMapping)parameterMappings.get(i);
if (parameterMapping.getMode() != ParameterMode.OUT) {
String propertyName = parameterMapping.getProperty();
Object value;
if (this.boundSql.hasAdditionalParameter(propertyName)) {
value = this.boundSql.getAdditionalParameter(propertyName);
} else if (this.parameterObject == null) {
value = null;
} else if (this.typeHandlerRegistry.hasTypeHandler(this.parameterObject.getClass())) {
value = this.parameterObject;
} else {
MetaObject metaObject = this.configuration.newMetaObject(this.parameterObject);
value = metaObject.getValue(propertyName);
}
//获得对应的TypeHandler
TypeHandler typeHandler = parameterMapping.getTypeHandler();
JdbcType jdbcType = parameterMapping.getJdbcType();
if (value == null && jdbcType == null) {
jdbcType = this.configuration.getJdbcTypeForNull();
} try {
//给Statement设置参数
typeHandler.setParameter(ps, i + 1, value, jdbcType);
} catch (TypeException var10) {
throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + var10, var10);
} catch (SQLException var11) {
throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + var11, var11);
}
}
}
} }
}

StatementHandler设置

可选类型

public enum StatementType {
STATEMENT, PREPARED, CALLABLE
}

xml设置

<select id="findAllStudents" resultMap="StudentResult" statementType="STATEMENT">
SELECT * FROM STUDENTS
</select>

mybatis源码阅读-执行器StatementHandle和ParameterHandler(五)的更多相关文章

  1. mybatis源码阅读-执行器Executor(四)

    说明 前面二看到了 sqlSession最终是找到MapperStatement然后委托给Executer执行的 Executer到底做了什么 接口定义 public interface Execut ...

  2. Mybatis源码阅读-配置文件及映射文件解析

    Mybatis源码分析: 1.配置文件解析: 1.1源码阅读入口: org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(); 功能:解析全局配置文 ...

  3. mybatis源码阅读心得

    第一天阅读源码及创建时序图.(第一次用prosson画时序图,挺丑..) 1.  调用 SqlSessionFactoryBuilder 对象的 build(inputStream) 方法: 2.   ...

  4. mybatis源码阅读(动态代理)

    这一篇文章主要是记录Mybatis的动态代理学习成果,如果对源码感兴趣,可以看一下上篇文章  https://www.cnblogs.com/ChoviWu/p/10118051.html 阅读本篇的 ...

  5. mybatis源码阅读-SqlSessionFactory和SqlSession(三)

    说明 读了3遍:https://my.oschina.net/zudajun/blog/665956 现在统一整理成笔记 并跟着源码一行一行调试 统一整理起来 SqlSession 接口定义 publ ...

  6. Mybatis源码阅读 之 玩转Executor

    承接上篇博客, 本文探究MyBatis中的Executor, 如下图: 是Executor体系图 本片博客的目的就是探究如上图中从顶级接口Executor中拓展出来的各个子执行器的功能,以及进一步了解 ...

  7. mybatis源码阅读-初始化过程(七)

    说明 mybatis初始化过程 就是解析xml到封装成Configuration对象 供后续使用 SqlSessionFactoryBuilder 代码例子 SqlSessionFactoryBuil ...

  8. mybatis源码阅读-初始化六个工具(六)

    六个基本工具图集 图片来源:https://my.oschina.net/zudajun/blog/668596 ObjectFactory 类图 接口定义 public interface Obje ...

  9. mybatis源码阅读-Transaction和TransactionFactory(四)

    Transaction 类图 接口定义 public interface Transaction { Connection getConnection() throws SQLException; v ...

随机推荐

  1. P4111 [HEOI2015]小Z的房间 生成树计数

    这个题是生成树计数的裸题,中间构造基尔霍夫矩阵,然后构成行列式,再用高斯消元就行了.这里高斯消元有一些区别,交换两行行列式的值变号,且消元只能将一行的数 * k 之后加到别的行上. 剩下就没啥了... ...

  2. 40. combo的displayField和valueField属性

    转自:https://xsl2007.iteye.com/blog/773464 下拉框combo可以设置displayField和valueField属性,这两个值值相当于Java中的map,一个键 ...

  3. 《Typecript 入门教程》 1、类

    类 使用class + 类名 即可定义一个类,一个类中通常有3个成员:属性.构造函数.方法: 在类内部引用属性或方法事使用this调用,它表示我们访问的是类的成员. 我们使用new构造了Greeter ...

  4. Django总结二

    - 创建app应用与ORM操作 - Django项目project - app(应用) -> 不同的功能放在不同的app中 - 命令 : - 创建app python manage.py sta ...

  5. what is success?

    什么是成功?这是个老话题了.然而每个人对成功的认识却也不同.记得央视主持人王志说过成功是相对的,每个人都有自己的成功标准.有的人认为有钱.有房.有车.有女人,就是成功.有的人则认为成功是你做了一件你想 ...

  6. springboot自定义常量配置

    现在你建一个类: import org.springframework.boot.context.properties.ConfigurationProperties; /** * Created b ...

  7. SAS进阶《深入解析SAS》之开发多语言支持的SAS程序

    SAS进阶<深入解析SAS>之开发多语言支持的SAS程序 1. 多语言支持的应用程序是指该程序在世界给第使用时,其能够处理的数据,以及处理数据的方式.信息展现的方式都符合当地的语言.文化习 ...

  8. eclipse整合maven下载jar包速度慢问题解决

    引用:http://blog.csdn.net/u010154380/article/details/70339538 开发过程中在pom.xml中添加pom的时候,默认是需要从中央仓库中下载,但是下 ...

  9. 背包系列 hdu3449 有依赖背包

    这道题真正困扰了笔者3,4天,冥思苦想几日无果之后,只能去找大牛的解法.结合网上的大牛解法与自己的理解,笔者终于解决了这个坑了,在此小庆幸一下. 原题如下: Consumer Time Limit: ...

  10. jsp 中包含 一个路径为变量的文件

    <head> <base href="<%=basePath%>"> <% String fileroot="MyJsp.jsp ...