Mybatis的执行流程解析

  • Post author:
  • Post category:其他




Mybatis的执行流程分析



前言

​ 我们都知道MyBtis是对JDBC的简易封装,它的出现某种程度了是为了消除所有的JDBC代码和参数的手工设置以及结果集的封装问题;所以想要理解MyBatis的执行流程,那就要先回顾一下JDBC的执行流程。




一、JDBC的执行流程

JBDC的底层主要是三个接口对象,Connection、Statement、ResultSet。

Connection用于建立与数据库的连接,Statement用于向数据库发送sql语句,ResultSet用于封装sql查询语句的结果。

原始的JDBC操作数据库主要有以下几个步骤:


1.注册驱动


使用 Class.forName() 方法加载数据库驱动程序类。


2.获取连接对象


JDBC的底层其实是使用Socket进行连接数据库的。


3.执行SQL语句,返回执行结果


通过获取Statement实例执行SQL语句。


4.处理执行结果


最后返回的结果集是ResultSetImpl。


5.释放资源

需要详细了解JBDC的读者请参考文章——

(7条消息) JBDC底层原理解析_如果我是枫的博客-CSDN博客

以上就是JDBC操作数据的流程步骤,然后我看下MyBatis的执行流程图。



二、

MyBatis执行流程


核心执行流程:

在这里插入图片描述

根据图中步骤,我们可以将这个执行流程分成了8个步骤。

1、读取MyBatis的核心配置文件。

mybatis-config.xml

为MyBatis的全局配置文件,用于配置数据库连接、属性、类型别名、类型处理器、插件、环境配置、映射器(mapper.xml)等信息,这个过程中有一个比较重要的部分就是映射文件其实是配在这里的;这个核心配置文件

最终会被封装成一个Configuration对象

2、加载映射文件。映射文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,映射文件是在mybatis-config.xml中加载;可以加载多个映射文件。

常见的配置的方式有两种,一种是package扫描包,一种是mapper找到配置文件的位置。

<!-- 使用包路径,扫描包下所有的接口,这种方式比较方便 --> 
<package name="com.mybatis.demo"/> 

<!-- resource:使用相对路径的资源引用-->
    
<!-- url:使用绝对类路径的资源引用-->
    
<!-- class:使用映射器接口实现类的完全限定类名-->
    
<mapper resource="xxx.xml"/>

3、构造会话工厂获取SqlSessionFactory。这个过程其实是用

建造者设计模式

使用SqlSessionFactoryBuilder对象构建的,SqlSessionFactory的最佳作用域是应用作用域。

//2. 创建SqlSessionFactory对象实际创建的是DefaultSqlSessionFactory对象
SqlSessionFactory builder = new	SqlSessionFactoryBuilder().build(inputStream);

4、创建会话对象SqlSession。由会话工厂创建SqlSession对象,对象中包含了执行SQL语句的所有方法,每个线程都应该有它自己的 SqlSession 实例。

SqlSession的实例不是线程安全的,因此是不能被共享的

,所以它的最佳的作用域是请求或方法作用域。

//3. 创建SqlSession对象实际创建的是DefaultSqlSession对象
  SqlSession sqlSession = builder.openSession();

5、Executor执行器。是MyBatis的核心,负责SQL语句的生成和查询缓存的维护,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护

  • SimpleExecutor – SIMPLE 就是普通的执行器。
  • ReuseExecutor-执行器会重用预处理语句(PreparedStatements)
  • BatchExecutor –它是批处理执行器

6、MappedStatement对象。MappedStatement是对解析的SQL的语句封装,一个MappedStatement代表了一个sql语句标签,如下:

<!--一个动态sql标签就是一个`MappedStatement`对象-->
<select	id="selectUserList"	resultType="com.mybatis.User"> 
  select * from t_user
</select>

7、输入参数映射。输入参数类型可以是基本数据类型,也可以是Map、List、POJO类型复杂数据类型,这个过程

类似于JDBC的预编译处理参数的过程

,有两个属性 parameterType和parameterMap

8、封装结果集。可以封装成多种类型可以是基本数据类型,也可以是Map、List、POJO类型复杂数据类型。封装结果集的过程就和JDBC封装结果集是一样的。也有两个常用的属性resultType和resultMap。

我们再来看一下这个完整的执行步骤,代码如下:

public class	MybatisTest {
public	static	void	main(String[]args) throws	Exception	{
 //	1.加载配置文件
 InputStream	inputStream =	Resources.getResourceAsStream("mybatis-config.xml");
 //2. 创建SqlSessionFactory对象实际创建的是DefaultSqlSessionFactory对象
SqlSessionFactory builder = new	SqlSessionFactoryBuilder().build(inputStream);
 //3. 创建SqlSession对象实际创建的是DefaultSqlSession对象
  SqlSession sqlSession = builder.openSession();
 //4. 创建代理对象
  UserMapper mapper = sqlSession.getMapper(UserMapper.class);
 //5. 执行查询语句
 List<User>	users = mapper.selectUserList();
 //6. 释放资源
  sqlSession.close();
  inputStream.close();
}
}

经过以上分析,我们了解了mybatis的核心流程,可以发现它和JDBC基本大同小异,比较明显的地方就是:

  1. 注册驱动获取链接的部分都抽取到了核心配置文件mybatis-config.xml中。
  2. sql语句抽取到了映射文件mapper.xml中。

​ 至于其他的部分,如执行sql预编译、执行查询、封装结果集等都是抽取到了其他的类中来完成这些操作。通过对JDBC执行步骤来对比分析MyBatis的执行的流程,总体上来看它们的执行步骤基本是一样的。

以下是mybatis的全部流程:

在这里插入图片描述



三、总结

​ 首先读取配置文件,然后加载映射文件,由SqlSessionFactory工厂对象去创建核心对象SqlSession,SqlSession对象会通过Executor执行器对象执行sql。然后Executor执行器对象会调用StatementHandler对象去真正的访问数据库执行sql语句。

​ 在执行sql语句前MapperStatement会先对映射信息进行封装,然后StatementHandler调用ParameterHandler去设置编译参数【#{},${}】,编译在StatementHandler中进行。然后StatementHandler调用JBDC原生API进行处理,获取执行结果,这个执行结果交给ResultSetHandler 来进行结果集封装,然后将结果返回给StatementHandler。


注意:

这里MapperStatement是对映射信息的封装,用于存储要映射的SQL语句的id、参数等信息。TypeHandler进行数据库类型和JavaBean类型映射处理。


我们其实可以发现,真正干活的是四个Hander,Executor的作用是用来协调。



版权声明:本文为qq_51634677原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。