MyBatis源码-解读Executor的三个实现类之SimpleExecutor(简单执行器)

简介: MyBatis源码-解读Executor的三个实现类之SimpleExecutor(简单执行器)

20200604232843431.png

Pre

MyBatis源码-深入理解MyBatis Executor的设计思想

工程部分见

MyBatis源码- SqlSession门面模式 & selectList 源码解析


20200614165442711.png



实际中,我们都是面向SqlSession编程的,不会直接调用Executor来执行业务逻辑,这里我们仅仅是为了深入了解下Executor体系架构才这么搞的,切记。


Executor 执行器

20200610163229121.png

接口继承关系



20200605171752866.png


这里我们重点看下Executor的 三个实现子类。

分别是:SimpleExecutor(简单执行器)、ReuseExecutor(重用执行器)、BatchExecutor(批处理执行器)。


SimpleExecutor(简单执行器)

入门小demo

package com.artisan;
import com.artisan.bean.User;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.SimpleExecutor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.transaction.jdbc.JdbcTransaction;
import org.junit.Test;
import java.sql.SQLException;
import java.util.List;
/**
 * @author 小工匠
 * @version v1.0
 * @create 2020-06-14 16:36
 * @motto show me the code ,change the word
 * @blog https://artisan.blog.csdn.net/
 * @description
 **/
public class ExecutorTest extends BaseTest {
    private MappedStatement ms;
    private JdbcTransaction jdbcTransaction;
    @Test
    public void test() throws SQLException {
        // 通过factory.openSession().getConnection()实例化JdbcTransaction ,用于构建SimpleExecutor
        jdbcTransaction = new JdbcTransaction(factory.openSession().getConnection());
        // 映射SQL
        ms = configuration.getMappedStatement("com.artisan.UserMapper.selectByid");
        // 实例化SimpleExecutor
        SimpleExecutor simpleExecutor = new SimpleExecutor(configuration, jdbcTransaction);
        // 调用doQuery执行查询
        List<User> userList = simpleExecutor.doQuery(ms, 1, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER, ms.getBoundSql(1));
        System.out.println(userList.get(0));
    }
}


20200614165526793.png


有了整体的了解以后,我们拆分来看下SimpleExecutor是如何工作的


实例化SimpleExecutor

首先我们要实例化一个SimpleExecutor ,看下SimpleExecutor的源码

两个参数

  public SimpleExecutor(Configuration configuration, Transaction transaction) {
    super(configuration, transaction);
  }

2020061417124338.png


使用JdbcTransaction 即可

jdbcTransaction = new JdbcTransaction(factory.openSession().getConnection());


doQuery方法

实例化完成以后,执行方法调用doQuery

  @Override
  public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
    .......
  }


我们可以看到这个方法是 @Override 重写父类的方法 ,去它的父类BaseExecutor看下该方法

BaseExecutor##doQuery

  protected abstract <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
      throws SQLException;


抽象方法 泛型支持


我们知道MyBatis Executor 有3个子类,父类中的抽象方法doQuery其实就是让子类去重写,实现不同的功能。


SimpleExecutor 、ReuseExecutor 、BatchExecutor 都是继承 BaseExecutor, 重写doQuery来实自身的特色功能 。


参数解读


MappedStatement : 映射SQL


Object parameter : SQL中的动态参数


RowBounds:分页用的,默认不分页 RowBounds.DEFAULT , 可参考 org.apache.ibatis.session.RowBounds


ResultHandler: 自定义处理返回结果 ,不使用写 Executor.NO_RESULT_HANDLER


BoundSql : 绑定的SQL


入参讲完了,我们来看下doQuery方法都做了些什么工作

  @Override
  public <E> List<E> 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);
      stmt = prepareStatement(handler, ms.getStatementLog());
      return handler.query(stmt, resultHandler);
    } finally {
      closeStatement(stmt);
    }
  }


获取大管家 Configuration

每次都要newStatementHandler ,这个StatementHandler 后面我们重点将,是专门处理JDBC的

prepareStatement --> BaseStatementHandler #prepare 方法

调用SimpleStatementHandler#query

我们看下执行过程的日志输出

17:50:42,538 DEBUG com.artisan.UserMapper.selectByid:143 - ==>  Preparing: select * from users where id = ? 
17:50:42,739 DEBUG com.artisan.UserMapper.selectByid:143 - ==> Parameters: 1(Integer)
17:50:42,808 DEBUG com.artisan.UserMapper.selectByid:143 - <==      Total: 1
User{id=1, name='artisan', age='11', sex='male', emal='123@qq.com', phoneNumber='12345', createTime=Thu Jun 04 08:00:00 CST 2020}

预编译 —执行SQL ----获取返回结果

我们加上两行代码在执行一遍

  List<User> userList2 = simpleExecutor.doQuery(ms, 1, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER, ms.getBoundSql(1));
  System.out.println(userList2.get(0));


20200614175422592.png


可以发现,相同的SQL 每次调用 都会预编译 ,我们期望的结果是 相同的SQL只要编译一次即可,那SimpleExecutor不支持,那怎么办呢

Executor 的另外一个实现类 ReuseExecutor 支持该功能 。 下篇博文我们来瞅瞅ReuseExecutor


相关文章
|
6月前
|
SQL XML Java
mybatis-源码深入分析(一)
mybatis-源码深入分析(一)
|
5月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
124 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
5月前
|
Java 数据库连接 mybatis
Springboot整合Mybatis,MybatisPlus源码分析,自动装配实现包扫描源码
该文档详细介绍了如何在Springboot Web项目中整合Mybatis,包括添加依赖、使用`@MapperScan`注解配置包扫描路径等步骤。若未使用`@MapperScan`,系统会自动扫描加了`@Mapper`注解的接口;若使用了`@MapperScan`,则按指定路径扫描。文档还深入分析了相关源码,解释了不同情况下的扫描逻辑与优先级,帮助理解Mybatis在Springboot项目中的自动配置机制。
284 0
Springboot整合Mybatis,MybatisPlus源码分析,自动装配实现包扫描源码
|
7月前
|
XML Java 数据库连接
mybatis源码研究、搭建mybatis源码运行的环境
这篇文章详细介绍了如何搭建MyBatis源码运行的环境,包括创建Maven项目、导入源码、添加代码、Debug运行研究源码,并提供了解决常见问题的方法和链接到搭建好的环境。
mybatis源码研究、搭建mybatis源码运行的环境
|
7月前
|
Web App开发 前端开发 关系型数据库
基于SpringBoot+Vue+Redis+Mybatis的商城购物系统 【系统实现+系统源码+答辩PPT】
这篇文章介绍了一个基于SpringBoot+Vue+Redis+Mybatis技术栈开发的商城购物系统,包括系统功能、页面展示、前后端项目结构和核心代码,以及如何获取系统源码和答辩PPT的方法。
|
2月前
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
93 2
|
5月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
239 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
5月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
154 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
5月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
1067 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
6月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理