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. [Codeforces 489E] Nastya and King-Shamans

    [题目链接] http://codeforces.com/contest/992/problem/E [算法] 线段树 + 二分 时间复杂度 : O(NlogN^2) [代码] #include< ...

  2. 什么是IaaS,PaaS和SaaS及其区别

    云计算的三种服务模式:IaaS,PaaS和SaaS Infrastructure(基础设施)-as-a-Service,Platform(平台)-as-a-Service,Software(软件)-a ...

  3. dB/oct 解释

    分频斜率(也称滤波器的衰减斜率)用来反映分频点以下频响曲线的下降斜率,用分贝/倍频程(dB/oct)来表示.它有一阶(6 dB/oct).二阶(12 dB/oct).三阶(18 dB/oct)和四阶( ...

  4. 编译android4.4 报错error: call to '__property_get_too_small_error' declared with attribute 的处理 (转载)

    转自:http://blog.csdn.net/syhost/article/details/14448899 完整的报错为: system/core/include/cutils/propertie ...

  5. P2533 [AHOI2012]信号塔

    传送门 据说是一个叫做随机增量法的东西 枚举\(i\),如果不在圆中将它设为圆心 枚举\(j\),如果不在圆中将\((i,j)\)成为新的圆的直径 枚举\(k\),如果不在圆中让\(i,j,k\)组成 ...

  6. 观察者模式-C#实现

    定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 观察者模式有四个角色:抽象主题.具体主题.抽象观察者.具体观察者. 抽象主题:把所有观察者对象 ...

  7. Android:用签名打包后微信分享失效

    刚开始使用微信分享,申请的微信appid也可以在直接使用,分享成功! 当我使用自己的签名打包分享时却分享失败,一闪而过,好郁闷的说,为什么之前没有打包就可以,签名打包后就不可以了... 开始查找各种资 ...

  8. Perforce 的基本使用教程

    一.简介 P4是什么 二.基本使用方法 1.下载代码 下载最新代码 Get Latest Revision 下载指定commit代码 Get Revision 2. 检出代码 选择指定目录,右键 Ch ...

  9. java攻城狮之路--复习JDBC(利用BeanUtils、JDBC元数据编写通用的查询方法;元数据;Blob;事务;批量处理)

    1.利用BeanUtils的前提得要加入以下两个jar包: commons-beanutils-1.8.0.jar commons-logging-1.1.1.jar package com.shel ...

  10. HDU_1079_思维题

    Calendar Game Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...