mybatis|mybatis源码学习篇之——执行流程分析

前言 在正式学习mybatis框架源码之前,需要先弄懂几个问题?myabtis框架是什么?为什么需要mybatis框架?使用mybatis框架带来的好处是什么?
回答这几个问题之前,我们先来看一下,之前在没有框架的时候,假如使用jdbc的方式进行开发,会怎样呢?下面来看一段使用jdbc的方式查询数据库的代码吧

public class TestJdbc {public static void main(String[] args) { Connection connection = null; PreparedStatement ps = null; ResultSet resultSet = null; String URL = "jdbc:mysql://IP:3306/test?characterEncoding=utf-8"; String USER = "root"; String PASSWORD = "123456"; try{ Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection(URL, USER, PASSWORD); String sql = "select * from user where username = ?"; ps = connection.prepareStatement(sql); ps.setString(1,"zhangfei"); resultSet = ps.executeQuery(); while (resultSet.next()){ System.out.println(resultSet.getInt("id") + ":" +resultSet.getString("address")); } }catch (Exception e){ e.printStackTrace(); }finally { try { resultSet.close(); ps.close(); connection.close(); }catch (Exception e){ e.printStackTrace(); } } }}

这段代码,就不用多做解释了吧,直接运行观察结果
mybatis|mybatis源码学习篇之——执行流程分析
文章图片

让我们来梳理一下在jdbc方式下,这个过程是怎么完成的呢?
1、创建一个connection对象
可以认为,上面的URL,USERNAME,PASSWORD属性都是为了创建与数据库交互的条件,Class.forName指定了要加载的数据库的连接驱动是哪种类型,这里是mysql类型的数据库,通过DriverManager.getConnection这一句,可以认为建立了一个与数据库连接的socket通道
mybatis|mybatis源码学习篇之——执行流程分析
文章图片

2、通过PreparedStatement创建预处理sql语句对象
使用PreparedStatement将外部传入的sql进行二次处理并包装成可执行的sql语句
mybatis|mybatis源码学习篇之——执行流程分析
文章图片

3、执行sql,并获取返回结果
将上一步得到的PreparedStatement通过connection传入sql执行器进行执行,得到结果集resultSet,如果获取到了执行结果,就封装在resultSet对象中,就可以解析resultSet
mybatis|mybatis源码学习篇之——执行流程分析
文章图片

从上面的分析来看,大致的步骤可分解为3步,创建连接对象,构建可执行的PreparedStatement,最后执行查询获取结果
其中,最关键的步骤想必大家都猜到了,集中在PreparedStatement这个对象的构建与执行中,这也是jdbc完成数据库的CRUD中最核心的一个对象组件
【mybatis|mybatis源码学习篇之——执行流程分析】但是我们发现,在sql语句比较简单的情况下,通过简单的参数拼接可以完成CRUD操作,一旦参数比较多,而且入参的方式不再是单一的参数而是对象,集合等,继续手动拼接,这个二工作量就比较大了
得到结果集之后,还需要我们通过遍历的方式手动去解析,需要对照字段的属性映射一一解析,当表的字段特别多的时候,这个可就比较折腾人了
综上所述,使用原生的JDBC的方式进行开发,在使用过程中存在诸多的不方便,导致开发人员将投入更多的时间和精力在这些琐碎的sql拼接与结果的解析上,因此需要一种框架,可以帮助开发人员更快的解决这个问题,把精力投入到业务开发中
mybatis解决的问题 了解了jdbc的问题之后,通过mybatis框架的使用,至少可以解决如下几个使用中的问题
  • 与JDBC相比,降低了至少一倍以上的代码量
  • 灵活,不会对应用程序或者数据库的现有设计强加任何影响,SQL写在XML里,从程序代码中彻底分离,降低耦合度,便于统一管理和优化,可重用
  • 提供XML标签,支持编写动态SQL语句(XML中使用if, else等)
  • 提供映射标签,支持对象与数据库的ORM字段关系映射(在XML中配置映射关系,也可以使用注解)
执行流程 从大的方面,将mybatis的执行流程图总结如下:
mybatis|mybatis源码学习篇之——执行流程分析
文章图片

1、mybatis配置文件
  • SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis
    的运行环境等信息
  • Mapper.xml,此文件作为mybatis的sql映射文件,文件中配置了操作数据
    库的sql语句。此文件需要在SqlMapConfig.xml中加载
2、 SqlSessionFactory
通过mybatis环境等配置信息构造SqlSessionFactory,即会话工厂
3、sqlSession
通过会话工厂创建sqlSession即会话,程序员通过sqlsession会话接口对数据库
进行增删改查操作
4、 Executor执行器
mybatis底层自定义了Executor执行器接口来具体操作数据库,Executor接口有
两个实现,一个是基本执行器(默认)、一个是缓存执行器,sqlsession底层是
通过executor接口操作数据库的
5、Mapped Statement
它是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个select\insert\update\delete标签对应一个Mapped Statement对象,select\insert\update\delete标签的id即是Mappedstatement的id
  • Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、
    pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql
    中,输入参数映射就是jdbc编程中对preparedStatement设置参数
  • Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、
    pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象
    中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程
调用过程流程图 mybatis|mybatis源码学习篇之——执行流程分析
文章图片

SqlSession
接收开发人员提供Statement Id 和参数.并返回操作结果
Executor
MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护
StatementHandler
封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合
ParameterHandler
负责对用户传递的参数转换成JDBC Statement 所需要的参数
ResultSetHandler
负责将JDBC返回的ResultSet结果集对象转换成List类型的集合
TypeHandler
负责java数据类型和jdbc数据类型之间的映射和转换
MappedStatement
维护了一条节点的封装
SqlSource
负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到
BoundSql对象中,并返回BoundSql表示动态生成的SQL语句以及相应的参数信息
Configuration
MyBatis所有的配置信息都维持在Configuration对象之中。
通过上面的执行流程图,以及执行过程中涉及到的各个组件作用,我们可以大致想象一下mybatis的执行一条sql查询时的完整链路,再具体点我们可以总结为如下这幅图,
mybatis|mybatis源码学习篇之——执行流程分析
文章图片

从代码层面的结构上进行剖析,可以将整个执行过程分为3步
  1. 解析配置文件,包括SqlMapConfig.xml以及与业务相关的xml文件
  2. 将解析好的配置文件,如属性映射,连接数据库信息等封装到Configuration对象
  3. 执行器执行CRUD并返回结果
当然,从上面的流程图上看,远比这3步要复杂,因为mybatis完成并了JDBC本身的功能同时,还进行了更深入的拓展,比如结果集的自动映射,动态sql语句等,而这些过程的执行,需要更多的组件共同配合完成,才有了上述众多的组件,下一篇我们通过源码的方式对其中的主要组件进行分析说明
本篇到此结束,最后感谢观看!

    推荐阅读