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. Map类型介绍与遍历

    声明:本文非原创: 在程序员开发过程中,Map有着利用率占比是非常高:很多时间我们只知其用,不知其理:写这个随笔的目的也是希望对伙伴们对Map的理解有一点帮助. 类型介绍 java自带各种Map类.统 ...

  2. PCB SQL SERVER 正则应用实例

    我们用过SQL SERVER的都知道,SQL SERVER它本身是不自带正则表达式的,因为没有,所以基本都没用过啊, 但我们在C#中对文本匹配用正则的方式处理非常好用,省得你写一堆代码实现匹配,多简洁 ...

  3. PCB javascript实现个税5000计算

    个税调整为5000计划实施是今年10月份.而明年一月份全面实施, 马上快到5000个税实施的日子了,当到了个税实施日子时,必定网络会产生热点,这个时候需要就是蹭热点的时候到来时. 全国网友肯定都会关心 ...

  4. Linux系统下vim常用快捷键及功能

    1. 什么是vim Vim是一个类似于Vi的著名的功能强大.高度可定制的文本编辑器,在vi的基础上改进和增加了很多特性. vim编辑器是Linux系统下标准的编辑器,作用相当于windows系统中的记 ...

  5. E20170807-mk

    literal adj. 照字面的; 原义的; 逐字的; 平实的,避免夸张;

  6. github 用户不被识别问题

    期末考完,继续开发. 用过的都知道,直接用的话贡献者上面显示不出自己. 查一下就知道是因为github的识别是靠邮箱设置的.   但是如果频繁创建新仓库,容易忘记设定用户名和邮箱.   突发奇想,发现 ...

  7. Tornado集成Apscheduler定时任务

    熟悉Python的人可能都知道,Apscheduler是python里面一款非常优秀的任务调度框架,这个框架是从鼎鼎大名的Quartz移植而来. 之前有用过Flask版本的Apscheduler做定时 ...

  8. Elasticsearch如何做到亿级数据查询毫秒级返回?

    阅读本文大概需要 6 分钟. 如果面试的时候碰到这样一个面试题:ES 在数据量很大的情况下(数十亿级别)如何提高查询效率? 这个问题说白了,就是看你有没有实际用过 ES,因为啥?其实 ES 性能并没有 ...

  9. 实战篇之实现 OutLook 中以 EDM 形式发送通知邮件

    1.写 Html5 的 EDM 模板 EDM 源代码示例: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ...

  10. JAVA小记(一)

    java中向上转型.向下转型.内部类中所需注意的问题: 向上转型与向下转型: 举个例子:有2个类,Father是父类,Son类继承自Father. Father f1 = new Son();   / ...