• MyBatis原理与执行流程


    首先感谢尚硅谷的老师讲解!

    Mybatis流程分四步

    1. 返回创建SqlSessionFactory对象
    2. 返回SqlSession的实现类DefaultSqlSession对象
    3. 返回一个MapperProxy的代理对象
    4. 执行询流程。

    第一步返回创建SqlSessionFactory对象

    SqlSessionFactoryBuilder().build(inputStream);

    如何得到配置文件的内容?  创建解析器解析全局配置文件

    XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);

    得到全局配置文件的配置内容 , 解析每一个标签把详细信息保存在Configuration

    //解析配置文件标签
    build(parser.parse());
     propertiesElement(root.evalNode("properties"));
          Properties settings = settingsAsProperties(root.evalNode("settings"));
          loadCustomVfs(settings);
          typeAliasesElement(root.evalNode("typeAliases"));
          pluginElement(root.evalNode("plugins"));
          objectFactoryElement(root.evalNode("objectFactory"));

    全局配置文件中有该属性可以解析mapper.xml文件 也保存到Configuration中

    mappers>
            <package name="dao" />
    </mappers>

    Mapper.xml中的每个元素解析出来保存到全局配置中

    将增删改查标签的每一个标签每一个属性也解析出来
    封装到一个MapperedStatement
    一个MapperedStatement就代表一个增删改查标签的详细信息
    最后 return configuration;
    包括全局配置信息和mapper.xml映射文件的各种信息

    返回的configuration通过build

    return new DefaultSqlSessionFactory(config);

    configuration中

          mapperRegistry属性保存的是代理类信息
          mappedStatement属性保存的是增删查改等标签内容

    总结:

    配置文件的信息解析保存到Configureation对象中
    返回包含Configureation的DefaultSqlSessionFactory

    第二步 返回SqlSession的实现类DefaultSqlSession对象

    他里面包含了Executor(是用来增删改查的)和Configuration。
    1. sqlSessionFactory.openSession();
    2. 创建:获取一些信息 创建事务Transaction tx
    3. configuration.newExecutor

    根据Exector在全局配置中的类型,
    创建出 BatchExecutor/ReuseExecutor/SimpleExecutor

    4. 判断是否配置了二级缓存:

    if (cacheEnabled)
    进行封装
    executor = new CachingExecutor(executor);
    5. 根据某列的值改变封装行为
    6. 调用拦截器方法,使用拦截器链
    使用每一个拦截器重新包装Executor返回

     executor = (Executor) interceptorChain.pluginAll(executor); 

    最后:

    new DefaultSqlSession(configuration, executor, autoCommit);

    总结:

    创建DefaultSqlSession返回,包含Configurarion和Executor

    第三步 getMapper使用MapperProxyFactory创建一个MapperProxy的代理对象

    代理对象里面包含了 DefaultSqlSession(Executor)
    动态代理对象就可以使用DefaultSqlSession中的Executor实现增删改查

    configuration.getMapper
    mapperRegistry.getMapper中:
    根据接口类型knownMappers.get(type)

    获得MapperProxyFactory 代理类工厂
    然后创建了代理类

    @SuppressWarnings("unchecked")
      protected T newInstance(MapperProxy<T> mapperProxy) {
        return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
      }
    public T newInstance(SqlSession sqlSession) {
        final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
        return newInstance(mapperProxy);
      }

    过程:创建MapperProxy,它是一个InvocationHandler
    然后创建MapperProxy的代理对象

    MapperProxy<T> implements InvocationHandler, Serializable {
    //里面有接口信息
     private final SqlSession sqlSession;
      private final Class<T> mapperInterface;
      private final Map<Method, MapperMethod> methodCache;

     

    第四步:一张图明白查询流程

    Mybatis总结:
    1.根据配置文件(全局和sql映射配置)初始化configuration对象
    2.创建一个DefaultSqlSession对象,它里面包含Configuration以及Executor(根据全局配置文件属性defaultExecutorType值,创建出对应Executor)
    3.DefaultSqlSession.getMapper():拿到Mapper接口对应的MapperProxy,
    4.MapperProxy里面有DefaultSqlSession(当然了DefaultSqlSession里面有Executor)
    5.执行正删改查方法:

      (1) (直接用的是代理对象,代理对象调用DefaultSqlSession[Exector]进行增删改查),Exector会创建
      (2) 一个Statement对象(同时也创建了StatementHandler,ParameterHandler,ResultSetHandler),
      (3) 调用StatementHandler的预编译参数以及设置参数值(ParameterHandler给Sql语句设置参数值)
      (4) 调用StatementHandler的增删改查方法
      (5) ResultSetHandler封装结果值

    用图说明一下流程:

    注意,四大对象每个创建的时候,都有一个拦截器链interceptorChain.pluginAll(parameterHandler),理解这个对些Mybatis的插件很有帮助.

    这里主要涉及到了插件,后面会介绍。这里简单知道 pluginAll是用来拦截四大对象,
    相当于web的拦截器作用

    转: https://blog.csdn.net/qq_38409944/article/details/82494187

  • 相关阅读:
    设计模式之八:外观模式(Facade)
    Python模块学习笔记— —time与datatime
    Android加载图片OOM错误解决方式
    [C#]Attribute特性(2)——方法的特性及特性参数
    [C#]Attribute特性
    [Winform]一个简单的账户管理工具
    [C#]AES加密算法实现
    [C#基础]ref和out的区别
    [Socket网络编程]一个封锁操作被对 WSACancelBlockingCall 的调用中断。
    [Socket网络编程]由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
  • 原文地址:https://www.cnblogs.com/fps2tao/p/13538271.html
Copyright © 2020-2023  润新知