MyBatis(4)Jdbc处理器StatementHandler解析

MyBatis Jdbc处理器StatementHandler解析

StatementHandler概要

MyBatis一个基于JDBC的Dao框架,但前面我们所学的会话、执行器半点没有提到jdbc,原因是MyBatis把所有跟JDBC相关的操作全部都放到了StatementHandler中。

一个SQL请求会经过会话,然后是执行器,最由StatementHandler执行jdbc最终到达数据库。其关系如下图:

这里要注意这三者之间比例是1:1:n。也就是说多个SQL操作对应一个会话,和唯一的执行器以及N个StatementHandler。这里的N取决于通过会话调用了多少次Sql(命中缓存除外)。

StatementHandler定义

JDBC处理器,基于JDBC构建JDBC Statement,并设置参数,然后执行Sql。每调用会话当中一次SQl,都会有与之相对应的且唯一的Statement实例。

StatementHandler结构

StatementHandler接口定义了JDBC操作的相关方法如下:

// 基于JDBC 声明Statement

Statement prepare(Connection connection, Integer transactionTimeout)

    throws SQLException;

// 为Statement 设置方法

void parameterize(Statement statement)

    throws SQLException;

// 添加批处理(并非执行)

void batch(Statement statement)

    throws SQLException;

// 执行update操作

int update(Statement statement)

    throws SQLException;

// 执行query操作

<E> List<E> query(Statement statement, ResultHandler resultHandler)

    throws SQLException;

StatementHandler 有三个子类SimpleStatementHandler、PreparedStatementHandler、CallableStatementHandler,分别对应JDBC中的Statement、PreparedStatement、CallableStatement。

大部分情况下都是预处理器,所以接下我们就针对PreparedStatementHandler来讲解其实现过程。

处理流程解析

总体流程

接下来了解statementHandler完整执行流程。如下时序图:

总共执行过程分为三个阶段:

  1. 预处理:这里预处理不仅仅是通过Connection创建Statement,还包括设置参数。

  2. 执行:包含执行SQL和处理结果映射两部分。

  3. 关闭:直接关闭Statement。

参数处理和结果集封装,涉及数据库字段和JavaBean之间的相互映射,相对复杂。所以分别使用ParameterHandler与ResultSetHandler两个专门的组件实现。接下来就一起了解一下参数处理与结果集封装的处理流程。

参数处理

参数处理即将Java Bean转换成数据类型。总共要经历过三个步骤,参数转换、参数映射、参数赋值。

参数转换

即将JAVA 方法中的普通参数,封装转换成Map,以便map中的key和sql的参数引用相对应。

@Select({"select * from users where name=#{name} or age=#{user.age}"})

@Options

User selectByNameOrAge(@Param("name") String name, @Param("user") User user);

  • 单个参数的情况下且没有设置@param注解会直接转换,勿略SQL中的引用名称。

  • 多个参数情况:优先采用@Param中设置的名称,如果没有则用参数序号代替 即"param1、parm2...."

  • 如果javac编译时设置了 -parameters 编译参数,也可以直接获取源码中的变量名称作为key

以上所有转换逻辑均在ParamNameResolver中实现。

参数映射

映射是指Map中的key如何与SQL中绑定的参数相对应。以下这几种情况

  • 单个原始类型:直接映射,勿略SQL中引用名称

  • Map类型:基于Map key映射

  • Object:基于属性名称映射,支持嵌套对象属性访问

在Object类型中,支持通过“.”方式映射属中的属性。如:user.age

参数赋值

通过TypeHandler 为PrepareStatement设置值,通常情况下一般的数据类型MyBatis都有与之相对应的TypeHandler

结果集封装

指读取ResultSet数据,并将每一行转换成相对应的对象。用户可在转换的过程当中可以通过ResultContext来控制是否要继续转换。转换后的对象都会暂存在ResultHandler中最后统一封装成list返回给调用方

结果集转换中99%的逻辑DefaultResultSetHandler 中实现。整个流程可大致分为以下阶段:

  1. 读取结果集

  2. 遍历结果集当中的行

  3. 创建对象

  4. 填充属性

06-02 157
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值