MyBatis原理机制详解(附8大执行流程图解)

MyBatis原理机制详解(附8大执行流程图解)-mikechen

MyBatis 是 Java 生态中非常著名的一款 ORM 框架,目前在一线互联网大厂中应用广泛,MyBatis已经成为了一个必会框架。

MyBatis工作原理,如下图所示 :

MyBatis原理机制详解(附8大执行流程图解)-mikechen

上面中流程就是MyBatis内部核心流程,一共会经历8大步骤,下面我会详解8大步骤。

第一步:读取MyBatis的配置文件

MyBatis-config.xml为MyBatis的全局配置文件,用于配置数据库连接信息。

如下所示:

<configuration>
    <!-- 和spring整合后 environments配置将废除 -->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc事务管理 -->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url"
                    value="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8" />
                <property name="username" value="root" />
                <property name="password" value="123456" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
       <mapper  resource="sqlMapper/userMapper.xml"/>
    </mappers>
</configuration>

mapper.xml:sql的映射文件,配置了操作数据库的sql语句,此文件需在config.xml中加载。

比如:加载用户映射信息UserMapper.xml。

<mappers> 
  <mapper resource="sqlMapper/userMapper.xml"/> 
</mappers>

 

第二步:加载映射文件

SQL的映射文件,配置了操作数据库的SQL语句,需要在MyBatis配置文件MyBatis-config.xml中加载。

MyBatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

如下所示:

<mappers> 
  <mapper resource="sqlMapper/userMapper.xml"/> 
</mappers>

MyBatis-config.xml 加载用户表,映射文件为:UserMapper.xml。

 

第三步:构造会话工厂

通过MyBatis的环境配置信息构建会话工厂SqlSessionFactory,用来开启SqlSession。

SqlSessionFactory是MyBatis框架中的一个接口,主要负责MyBatis框架初始化操作及为开发人员提供SqlSession对象。

它有两个实现类:DefaultSqlSessionFactory和SqlSessionManager,其中SqlSessionManager已被废弃。

在Mybtis初始化的过程中首先会读取MyBatis的核心配置文件,一般创建SqlSessionFactory的代码如下:

//使用 SqlSessionFactoryBuilder 构建 SqlSessionFactory
SqlSessionFactory SqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

SqlSessionFactoryBuilder通过Configuration对象生成SqlSessionFactory,用来开启SqlSession。

 

第四步:创建会话对象

由会话工厂创建SqlSession对象,该对象中包含了执行SQL语句的所有方法,SqlSession对象完成和数据库的交互。

SqlSession提供select、insert、update、delete方法,用于完成和数据库的交互。

 

第五步:Executor执行器

MyBatis底层定义了一个Executor接口来操作数据库,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。

Execute执行器起到至关重要的作用,它是真正执行Java与数据库交互的东西,参与了整个SQL查询执行过程中。

主要有三种执行器:

  • 简易执行器SIMPLE(不配置就是默认执行器);
  • REUSE是一种重用预处理语句;
  • BATCH批量更新批量专用处理器
public enum ExecutorType {
  SIMPLE, REUSE, BATCH
}

 

第六步:MappedStatement对象

在Executor接口的执行方法中有一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等信息。

在Executor中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.<E>query(stmt, resultHandler);
   } finally {
     closeStatement(stmt);
   }
 }

 

第七步:输入参数映射

输入映射,是在映射文件中通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型。

假设现在有个比较复杂的查询需求:完成用户信息的综合查询,需要传入查询条件很复杂。

可能包括:用户信息、其它信息,比如:商品、订单等,那么我们单纯的传入一个User就不行了,所以首先我们得根据查询条件,自定义一个新的pojo,在这个pojo中包含所有的查询条件。

package com.MyBatis.entity;

public class UserQueryVo {
    
    //在这里添加所需要的查询条件
    //用户查询条件,这里假设一个User就已经够了
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }   

    //可以包装其他的查询条件,比如订单、商品等
    //......    

}

 

第八步:输出结果映射

使用resultType进行输出映射,输出结果类型可以是Map、List等集合类型,只有查询出来的列名和POJO中的属性名一致,该列才可以映射成功。

拆解,后续我将重点分析其核心源码,这样先全局再局部,这样更有利于掌握其核心原理实现,希望这个框架系列能对你有所用。

陈睿mikechen

10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注「mikechen」公众号,获取更多技术干货!

后台回复面试即可获取《史上最全阿里Java面试题总结》,后台回复架构,即可获取《阿里架构师进阶专题全部合集

评论交流
    说说你的看法