美文网首页
MyBatis运行原理分析

MyBatis运行原理分析

作者: 一起码 | 来源:发表于2020-04-30 18:28 被阅读0次

在了解MyBatis的运行流程前,先快速了解下MyBatis的四大核心组件,MyBatis的整个执行流程都是围绕这四个组件进行的。

  • SqlSessionFactoryBuilder(构造器),会根据配置信息或者代码来生成SqlSessionFactory(工厂接口)
  • SqlSessionFactory,用来生成SqlSession(会话)
  • SqlSession,是一个既可以发送SQL去执行并返回结果,也可以获取Mapper的接口
  • SQL Mapper,由一个Java接口和XML文件(或注解)构成的,需要给出对应的SQL和映射规则,它负责发送SQL去执行,并返回结果

MyBatis的运行分为两部分

  • 第一部分是读取配置文件缓存到Configuration对象,用来创建SqlSessionFactory
  • 第二部分是SqlSession的执行过程
    下面将详细分析这两部分

构建SqlSessionFactory

  1. 通过XMLConfigBuilder(org.apache.ibatis.builder.xml)解析配置的XML文件,读出配置参数,并将读取的数据存入Configuration(org.apache.ibatis.session)对象中。
  2. 使用Configuration对象去创建SqlSessionFactory,SqlSessionFactory是一个接口,MyBatis提供了一个默认实现类DefaultSqlSessionFactory(org.apache.ibatis.session.defaults),大部分场景下都不需自己创建SqlSessionFactory实现类

SQLSession运行过程

构建SqlSessionFactory就可以拿到SqlSession,SqlSession提供了增、删、查、改方法,在旧版本的MyBatis或iBatis中基本是直接使用这些方法,在新版本中则是建议使用Mapper,其中Mapper映射是通过动态代理来实现的

SqlSession的四大对象

Mapper映射器通过动态代理对象进入到MapperMethed的execute方法,经过简单判断就可以进入增、删、查、改等方法,然后Mapper的执行过程是通过Executor、StatementHandler、ParameterHandler和ResultHandler来完成数据库操作和结果返回。

Executor

代表执行器,由它来调度StatementHandler、ParameterHandler、ResultHandler等来执行对应的SQL,是一个真正执行Java和数据库交互的东西,有三种执行器,可以通过setting元素中的defaultExecutorType来配置
1. SIMPLE,简易执行器,也是默认的执行器
2. REUSE,重用预处理语句
3. BATCH,执行重用语句和批量更新,是针对批量专用的执行器

StatementHandler

使用数据库的Statement(PrepardStatement)执行操作,它是四大对象的核心,起承上启下的作用,StatementHandler是专门处理数据库会话,Configuration生成StatementHandler会话器的逻辑如下

  public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
  
    StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
    
    statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
    return statementHandler;
  }

其中RoutingStatementHandler是StatementHandler的一个具体实现,但不是我们使用的真实对象,它是通过适配模式找到对应的StatementHandler来执行的,主要分为三种
1. SimpleStatementHandler直接使用普通的Statement对象,这样每次执行SQL语句都需要数据库对SQL进行预编译
2. PreparedStatementHandler使用PrepareStatement执行,虽然初次创建PrepareStatement时开销比较大,但在多次处理SQL时只需要初始化一次,可以有效提高性能
3. CallableStatementHandler使用CallableStatement执行,CallableStatement是用来执行存储过程的
各模式执行查询的流程类似,都是实现三个主要方法prepare、parameterize和query

ParameterHandler

用于SQL对参数的处理ParameterHandler(org.apache.ibatis.executor.parameter)的接口定义如下

public interface ParameterHandler {
  Object getParameterObject();
  void setParameters(PreparedStatement ps)
      throws SQLException;
}

默认提供了DefaultParameterHandler实现类
1. getParameterObject返回参数对象
2. setParameters设置预编译SQL语句的参数,主要是从parameterObject对象中取参数,然后使用typeHandler进行参数处理,typeHandler是注册在Configuration里

ResultHandler

是进行最后数据集(ResultSet)的封装返回处理,ResultSetHandler(org.apache.ibatis.executor.resultset)的接口定义如下

public interface ResultSetHandler {
  <E> List<E> handleResultSets(Statement stmt) throws SQLException;
  <E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException;
  void handleOutputParameters(CallableStatement cs) throws SQLException;
}

默认提供了一个实现类DefaultResultSetHandler,实现比较复杂,会涉及Javassist或者CGLIB作为延迟加载,然后通过typeHandler和ObjectFactory进行组装结果再返回。
1. handleOutputParameters是处理存储过程输出参数的
2. handleResultSets是封装结果集的
3. handleCursorResultSets是封装批处理结果集

SqlSession运行流程图如下


MyBatis SqlSession运行流程

SqlSession是通过Executor创建StatementHandler来运行的,而StatementHandler要经过下面三步:

  1. prepared预编译SQL
  2. parameterize设置参数
  3. query/update执行SQL
    其中parameterize是调用parameterHandler的方法去设置的,而参数是根据类型处理器typeHandler去处理的,query/update方法是通过ResultHandler进行处理结果的封装,如果是update语句,就返回整数,否则通过typeHandler处理结果类型,然后用ObjectFactory提供的规则组装对象,返回给调用者。这就是SqlSession的主要执行过程

相关文章

网友评论

      本文标题:MyBatis运行原理分析

      本文链接:https://www.haomeiwen.com/subject/riytghtx.html