Mybatis的解析和运行原理

Posted Demrystv

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis的解析和运行原理相关的知识,希望对你有一定的参考价值。

Mybatis的解析和运行原理

  

  Mybatis的运行过程大致分为两大步:第一步,读取配置文件缓存到Configuration对象,用以创建 SqlSessionFactory;第二步,SqlSession的执行过程。其中第一步中, SqlSessionFactory的创建过程比较简单,第二步中, SqlSession的执行过程较为复杂,其底层需要用到反射技术和动态代理的知识。

 

1. 构建 SqlSessionFactory过程

   SqlSessionFactory是Mybatis的核心类之一,其重要的功能是提供创建Mybatis的核心接口 SqlSession,所以要先创建 SqlSessionFactory,在Mybatis中,它采用了 Builder的模式去创建 SqlSessionFactory,在实际中可以通过 SqlSessionFactoryBuilder 去构建,其构建分为两步:

  第1步:通过org.apache.ibatis.builder.xml.XMLConfiguration解析配置的XML 文件,读出所配置的参数,并将读取的内容存入到org.apache.ibatis.session.Configuration类对象中。而Configuration对象采用的是单例模式,几乎所有的Mybatis配置内容都会存放在这个单例对象中,以便后续将这些内容读出。

  第2步:使用Configuration对象去创建SqlSessionFactory,Mybatis中的SqlSessionFactory是一个接口,而不是一个实现类,为此Mybatis提供了一个默认的实现类org.apache.ibatis.session.defaults.DefaultSqlSessionFactory。在大部分情况下都没必要自己去创建新的SqlSessionFactory实现类。

  这种创建方式就是一种Builder模式,对于复杂的对象而言,使用构造参数很难实现,这时使用一个类(比如Configuration)作为统领,一步步构建所需的内容,然后通过他去创建最终的对象(比如SqlSessionFactory),这样比较清晰,思路值得我们去学习和参考。

 

1.1 构建Configuration

  在SqlSessionFactory构建中,configuration是最重要的,它的作用是:

  ①读入配置文件,包括基础配置的XML和映射器XML(或注解)。

  ②初始化一些基础配置,比如Mybatis的别名等,一些重要的类对象(比如插件、映射器、Object工厂、typeHandlers对象等)。

  ③提供单例,为后续创建SessionFactory服务,提供配置的参数。

  ④执行一些重要对象的初始化方法。

  Configuration是通过XMLConfigurationBuilder去构建的,首先它会读出所有XML配置的信息,然后把他们解析并保存在Configuration单例中。它会对如下内容进行初始化:全局参数、别名、插件、对象工厂、对象包装工厂、反射工厂、环境设置、数据库环境、数据库标识、类型转换器和映射器等等。

 

1.2 构建映射器的内部组成

  当XMLConfigBuilder解析XML时,会将每一个SQL和其配置的内容保存起来。一般而言,在Mybatis中一条SQL和它配置信息主要由3个部分组成,分别是MappedStatement、SqlSource和BoundSql

  ①MappedStatement的作用是保存一个映射器节点的内容,它是一个类,包括配置的SQL、SQL中的id、缓存信息、resultType、resultMap等配置内容,它还有一个重要的属性sqlSource。

  ②SqlSource是提供BoundSql的地方,它是MappedStatement的一个属性,它的作用是根据上下文和参数解析生成需要的SQL。

  ③BoundSql是一个结果对象,也就是SqlSource通过对SQL和参数的联合解析得到的SQL和参数。

 

1.3 构建SqlSessionFactory

SqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

  Mybatis会根据文件流先生成Configuration对象,进而构建SqlSessionFactory对象。

 

2.SqlSession运行过程

 

2.1映射器(Mapper)的动态代理

 

  在程序的编写过程中,我们经常写这样的代码:

RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);

  通过看Mybatis的源码可以得知,它是运用了configuration对象的getMapper方法,来获取对应的接口的对象的,其底层又运用了映射器的注册器MapperRegistry来获取对应的接口对象,首先它判断是否注册一个Mapper,如果没有则会抛出异常信息,如果有,就会启用MapperProxyfactory工厂来生成一个代理实例。Mapper映射是通过动态代理来实现的,这里可以看到动态代理对接口的绑定,它的作用是生成动态代理对象(占位),而代理的方法则是放到了MapperProxy类中。在看MapperProxy的源码,可以发现invoke的方法逻辑。如果Mapper是一个JDK动态代理对象,那么它就会运行到invoke方法里面。invoke首先判断是否是一个类,这里mapper是一个接口不是类,所以判定失败,然后生成MapperMethod对象,它是通过cachedMapperMethod方法对其初始化。最后执行execute方法,把sqlSession和当前运行的参数传递进去。

  通过分析源码我们可以得知,Mybatis为什么只用Mapper接口就能运行了,因为mapper的XML文件的命名空间对应的是这个接口的全限定名,而方法就是那条SQL的id,这样Mybatis就可以根据全路径和方法名,将其和代理对象绑定起来。通过动态代理技术,让这个接口运行其阿里,后面采用命令模式。最后使用SqlSession接口的方法是的它能够执行对应的SQL,只有有了这层封装,就可以采用接口编程。

 

2.2 SqlSession的四大对象

   ①Executor代表执行器,由它调度StatementHandler、ParameterHandler、ResultSetHandler等来执行对应的SQL,其中StatementHandler是最重要的。

  ②StatementHandler的作用是使用数据库的Statement执行操作,它是四大对象的核心,起到承上启下的作用,许多重要的插件都是通过拦截它来实现的。

  ③ParameterHandler是用来处理SQL参数的。

  ④ResultSetHandler是进行数据集的封装返回处理的。

以上是关于Mybatis的解析和运行原理的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis原理分析之三:初始化(配置文件读取和解析)

MyBatis原理解析之运行原理

互联网轻量级框架SSM-查缺补漏第七天(MyBatis的解析和运行原理)

mybatis运行原理

mybatis运行原理

Mybatis运行原理