• MyBatis-执行流程简介


    目录

     一、获取SqlSessionFactory

    二、获取SqlSession

    三、生成代理对象

    四、执行Excutor

    五、匹配执行SQL语句


     一、获取SqlSessionFactory

            SqlSessionFactory 有两个实现类:

                    一个是 SqlSessionManager 类,

                    一个是 DefaultSqlSessionFactory

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

  • 相关阅读:
    淘宝母婴购物数据分析
    户外运动耳机如何选择、最优秀的五款户外运动耳机推荐
    配置Swagger开发环境有效,生产环境无效
    【GOF】三种工厂模式~
    轻量封装WebGPU渲染系统示例<21>- 3D呈现元胞自动机之生命游戏(源码)
    解密Prompt系列10. 思维链COT原理探究
    C#通过Process调用Python脚本
    python爬取百度图片
    Hystrix原理
    std::async简单使用
  • 原文地址:https://blog.csdn.net/weixin_62427168/article/details/127573281