MyBatis-执行流程简介

目录

 一、获取SqlSessionFactory

二、获取SqlSession

三、生成代理对象

四、执行Excutor

五、匹配执行SQL语句


 一、获取SqlSessionFactory

        SqlSessionFactory 有两个实现类:

                一个是 SqlSessionManager 类,

                一个是 DefaultSqlSessionFactory

  • DefaultSqlSessionFactory : SqlSessionFactory 的默认实现类,是真正生产会话的工厂类,这个类的实例的生命周期是全局的,它只会在首次调用时生成一个实例(单例模式),就一直存在直到服务器关闭。
  • SqlSessionManager :已被废弃,原因大概是: SqlSessionManager 中需要维护一个自己的线程池,而使用MyBatis 更多的是要与 Spring 进行集成,并不会单独使用,所以维护自己的 ThreadLocal 并没有什么意义,所以 SqlSessionManager 已经不再使用。
//使用建造者模式的设计思想
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSessionFactory创建流程: 

  1. 通过mybatis的Resources来读取全局配置文件,然后以的形式作为SqlSessionFactoryBuilderbuild方法的参数传入;
  2. SqlSessionFactoryBuilder根据参数创建XMLConfigBuilder对象,然后调用parse方法生成Configuration对象;
  3. 然后SqlSessionFactoryBuilder根据Configuration对象作为参数,调用重载方法build,生成DefaultSqlSessionFactory对象并返回

        注: 

        解析mapper.xml时,Mybatis会把每个SQL标签封装成SqlSource对象,然后根据SQL语句的不同,又分为动态SQL静态SQL。其中,静态SQL包含一段String类的sql语句;而动态SQL则是由一个个SqlNode组成。 

        Mybatis会为每个SQL标签生成MappedStatement对象,保存在Configuration对象中。

        MappedStatement结构:

  • id:全限定类名+方法名组成的ID

  • sqlSource:当前SQL标签对应的SqlSource对象

二、获取SqlSession

SqlSession sqlSession = sqlSessionFactory.openSession();

        通过 SqlSessionFactory 对象得到 SqlSession,然后就可以执行 SQL 语句了。该过程中主要创建了两个与我们分析执行流程重要的对象,一个是 Executor 执行器对象,一个是 SqlSession 对象

        SqlSession 中定义了一系列模版方法,让你能够执行简单的 CRUD 操作,也能获取映射管理事务,例如涉及事务的 commit、 rollback、close 等方法。这是模版设计模式的一种应用。(SqlSession 本身不做任何业务处理操作,交给Excutor执行)

三、生成代理对象

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        MapperProxy Mapper 映射 SQL 语句的关键对象,我们写的 Mapper 层都是通过 MapperProxy 来和对应的 SQL 语句进行绑定的。

        调用过程

        SqlSession -> Configuration -> MapperRegistry -> MapperProxyFactory,最终执行了

        Proxy.newProxyInstance(),最终生成了MapperProxy

        当我们调用mapper接口方法的时候,实际调用到代理对象invoke()方法,最后其实是调用了Executor中的逻辑。

四、执行Excutor

        每一个 SqlSession 都会拥有一个 Executor 对象。Executor 核心作用是处理SQL请求、事务管理、维护缓存以及批处理等 。执行器在的角色更像是一个管理员,接收SQL请求,然后根据缓存、批处理等逻辑来决定如何执行这个SQL请求。并交给JDBC处理器执行具体SQL。

        Executor有主要的三个实现子类。分别是:SimpleExecutor(简单执行器)、ReuseExecutor(重用执行器)、BatchExecutor(批处理执行器)。

        简单执行器
        SimpleExecutor是默认执行器,它的行为是每处理一次会话当中的SQl请求都会通过对应的StatementHandler 构建一个新的Statement,这就会导致即使是相同SQL语句也无法重用Statement,所以就有了(ReuseExecutor)可重用执行器

        可重用执行器
        ReuseExecutor 区别在于他会将在会话期间内的Statement进行缓存,并使用SQL语句作为Key。所以当执行下一请求的时候,不再重复构建Statement,而是从缓存中取出并设置参数,然后执行。

        批处理执行器
        BatchExecutor 顾名思议,它就是用来作批处理的。但会将所有SQL请求集中起来,最后调用Executor.flushStatements() 方法时一次性将所有请求发送至数据库。

         Executor还有BaseExecutor(基础执行器)和CachingExecutor(缓存执行器)。

        基础执行器

        主要是用于维护缓存和事务。它实现了Executor中的queryupdate方法。处理SQL请求时先根据SQL参数判断缓存中是否存在数据,有就走缓存。否则就会交给下面的子类处理。BaseExecutor 只有一级缓存

        缓存执行器

        其实是二级缓存。二级缓存可以通过参数控制关闭,而一级缓存不可以。二级缓存采用了装饰者设计模式,处理完二级缓存逻辑之后,把SQL执行相关的逻辑交给实际的Executor处理(交由BaseExecutor 以及其子类处理)
 

五、匹配执行SQL语句

         在实际的一次调用中,Excutor会调用到MapperMethodexecute()方法并进入查询的逻辑分支。

        MapperMethod关联着本次执行方法所对应的SQL语句以及入参出参等信息,当mapper方法被调用的时候对应的MapperProxy会生成相应的MapperMethod并且会缓存起来

MapperMethod的两大属性:

   SqlCommand - MappedStatement信息和类型信息(SELECTUPDATE...

    MethodSignature 方法的参数信息和返回值信息

        在上述的MapperMethodexecute()方法中,会根据这两个属性进入不同的分支,(首先查缓存)在具体分支的方法中通过根据属性信息( “全限定类名+方法名” )拿到MappedStatement对象,然后通过Executor 交给StatementHandler 执行里面封装的Sql语句

        StatementHandler 负责基于实例化操作 Statement 对象与数据库进行交互,在工作时还会使用 ParameterHandler ResultSetHandler参数进行映射,对结果进行实体类绑定

ParameterHandler 负责为 PreparedStatement 的 sql 语句参数动态赋值

ResultSetHandler 负责处理 Statement 执行后产生的结果集,生成结果列表,并处理存储过程执行后的输出参数,返回给客户端

        SimpleStatementHandler: 管理 Statement 对象并向数据库中推送不需要预编译的SQL语句。

        PreparedStatementHandler: 管理 Statement 对象并向数据中推送需要预编译的SQL语句。

        CallableStatementHandler:管理 Statement 对象并调用数据库中的存储过程。

  • 4
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值