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

这篇具有很好参考价值的文章主要介绍了mybatis源码学习之mybatis执行流程分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Mybatis执行流程分析

mybatis全局配置文件

mybatis全局配置文件中涉及的标签如下图所示
mybatis源码学习之mybatis执行流程分析

配置文件解析

  public static void main(String[] args) throws IOException {

    // 读取配置文件
    InputStream is = Resources.getResourceAsStream("org/apache/ibatis/builder/MapperConfig1.xml");
    // 创建SqlSessionFactory工厂
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = sqlSessionFactoryBuilder.build(is);
    // 使用工厂生产SqlSession对象
    SqlSession session = factory.openSession();
     //使用SqlSession创建Dao接口的代理对象
    AuthorMapper authorMapper = session.getMapper(AuthorMapper.class);
    List<Author> authors = authorMapper.selectAllAuthors();
    //释放资源
    session.close();
    is.close();
  }

下面我们来进行源码分析。

配置文件的解析&创建SqlSessionFactory

配置文件的解析主要涉及到的类如下:XMLConfigBuilder、XPathParser、XPath、XNode,其中XPath、XNode是对
1、build方法内部首先会根据输入流等信息创建XMLConfigBuilder类的实例对象,然后调用XMLConfigBuilder实例的parse方法对配置文件进行解析;这里需要注意的是parse方法最后返回的是一个Configuration对象
mybatis源码学习之mybatis执行流程分析

2、parse方法则是调用了XPath对象的evalNode方法对配置文件中的configuration节点进行解析,会把节点内容放在XNode对象中然后返回;
mybatis源码学习之mybatis执行流程分析

3、parseConfiguration方法会对configuration节点解析出来的内容再进行解析,会把解析出来的内容放在configuration对象中;实际上配置文件中的内容解析出来后都会存到Configuration中
mybatis源码学习之mybatis执行流程分析

4、parseConfiguration方法中主要做的事如下:

  • 解析 properties节点
      /**
       * 解析 properties节点
       *     <properties resource="mybatis/db.properties" />
       *     解析到org.apache.ibatis.parsing.XPathParser#variables
       *           org.apache.ibatis.session.Configuration#variables
       */
      // issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
  • 解析settings节点
      /**
       * 解析我们的mybatis-config.xml中的settings节点
       * 具体可以配置哪些属性:http://www.mybatis.org/mybatis-3/zh/configuration.html#settings
       * <settings>
       <setting name="cacheEnabled" value="true"/>
       <setting name="lazyLoadingEnabled" value="true"/>
       <setting name="mapUnderscoreToCamelCase" value="false"/>
       <setting name="localCacheScope" value="SESSION"/>
       <setting name="jdbcTypeForNull" value="OTHER"/>
       ..............
       </settings>
       *
       */
      Properties settings = settingsAsProperties(root.evalNode("settings"));
  • 解析
      /**
       * 基本没有用过该属性
       * VFS含义是虚拟文件系统;主要是通过程序能够方便读取本地文件系统、FTP文件系统等系统中的文件资源。
       Mybatis中提供了VFS这个配置,主要是通过该配置可以加载自定义的虚拟文件系统应用程序
       解析到:org.apache.ibatis.session.Configuration#vfsImpl
       */
      loadCustomVfs(settings);
  • 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。
      /**
       * 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。
       * SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING
       * 解析到org.apache.ibatis.session.Configuration#logImpl
       */
      loadCustomLogImpl(settings);
  • 解析别名
      /**
       * 解析别名
       * <typeAliases>
       <typeAlias alias="Author" type="cn.tulingxueyuan.pojo.Author"/>
       </typeAliases>
       <typeAliases>
       <package name="cn.tulingxueyuan.pojo"/>
       </typeAliases>
       解析到oorg.apache.ibatis.session.Configuration#typeAliasRegistry.typeAliases
       */
      typeAliasesElement(root.evalNode("typeAliases"));
  • 解析插件
      /**
       * 解析我们的插件(比如分页插件)
       * mybatis自带的
       * Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
       ParameterHandler (getParameterObject, setParameters)
       ResultSetHandler (handleResultSets, handleOutputParameters)
       StatementHandler (prepare, parameterize, batch, update, query)
       解析到:org.apache.ibatis.session.Configuration#interceptorChain.interceptors
       */
      pluginElement(root.evalNode("plugins"));
  • 设置settings
      // 设置settings 和默认值
      settingsElement(settings);
  • 解析mybatis环境
      /**
       * 解析mybatis环境
       <environments default="dev">
       <environment id="dev">
       <transactionManager type="JDBC"/>
       <dataSource type="POOLED">
       <property name="driver" value="${jdbc.driver}"/>
       <property name="url" value="${jdbc.url}"/>
       <property name="username" value="root"/>
       <property name="password" value="Zw726515"/>
       </dataSource>
       </environment>

       <environment id="test">
       <transactionManager type="JDBC"/>
       <dataSource type="POOLED">
       <property name="driver" value="${jdbc.driver}"/>
       <property name="url" value="${jdbc.url}"/>
       <property name="username" value="root"/>
       <property name="password" value="123456"/>
       </dataSource>
       </environment>
       </environments>
       *  解析到:org.apache.ibatis.session.Configuration#environment
       *  在集成spring情况下由 spring-mybatis提供数据源 和事务工厂
       */
      // read it after objectFactory and objectWrapperFactory issue #631
      environmentsElement(root.evalNode("environments"));
  • 解析数据库厂商
      /**
       * 解析数据库厂商
       <databaseIdProvider type="DB_VENDOR">
       <property name="SQL Server" value="sqlserver"/>
       <property name="DB2" value="db2"/>
       <property name="Oracle" value="oracle" />
       <property name="MySql" value="mysql" />
       </databaseIdProvider>
       *  解析到:org.apache.ibatis.session.Configuration#databaseId
       */
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
  • 解析类型处理器
      /**
       * 解析我们的类型处理器节点
       * <typeHandlers>
       <typeHandler handler="org.mybatis.example.ExampleTypeHandler"/>
       </typeHandlers>
       解析到:org.apache.ibatis.session.Configuration#typeHandlerRegistry.typeHandlerMap
       */
      typeHandlerElement(root.evalNode("typeHandlers"));
  • 解析mapper文件
      /**
       * 解析mapper文件(SQL映射文件)
       *
       resource:来注册我们的class类路径下的
       url:来指定我们磁盘下的或者网络资源的
       class:
       若注册Mapper不带xml文件的,这里可以直接注册
       若注册的Mapper带xml文件的,需要把xml文件和mapper文件同名 同路径
       -->
       <mappers>
       <mapper resource="mybatis/mapper/EmployeeMapper.xml"/>
       <mapper class="com.tuling.mapper.DeptMapper"></mapper>


       <package name="com.tuling.mapper"></package>
       -->
       </mappers>
       * package 1.解析mapper接口 解析到:org.apache.ibatis.session.Configuration#mapperRegistry.knownMappers
       2.
       */
      mapperElement(root.evalNode("mappers"));

到这里配置文件就解析完了,mybatis会根据configuration对象创建SqlSessionFactory类的对象。

获取SqlSession

调用openSession()方法获取SqlSession
mybatis源码学习之mybatis执行流程分析
mybatis源码学习之mybatis执行流程分析

创建Executor的对象,这里会根据类型去创建对应的Executor
mybatis源码学习之mybatis执行流程分析

最后一行的代码:interceptorChain.pluginAll(executor)的作用是会调用所有拦截器对象的plugin方法
mybatis源码学习之mybatis执行流程分析

mybatis源码学习之mybatis执行流程分析
最后执行到Plugin类的wrap方法对executor进行包装
mybatis源码学习之mybatis执行流程分析

执行getMapper方法

实际上调用的是configuration对象的getMapper方法
mybatis源码学习之mybatis执行流程分析

而configuration对象则是调用了mapperRegistry对象的getMapper方法;
mybatis源码学习之mybatis执行流程分析

MapperRegistry简介

  • MapperRegistry实质上是一个Map,里面注册了启动过程中解析的各种mapper.xml;
  • MapperRegistry的key是接口的Class类型,MapperRegistry的value是MapperProxyFactory,用于生成对应的MapperProxy(动态代理类);
  • 由于Mybatis中的Mapper接口没有实现类,所以MapperProxy这个代理对
    象中没有委托类,也就是说MapperProxy干了代理类和委托类的事情
    mybatis源码学习之mybatis执行流程分析

接着往下看;mapperRegistry的getMapper方法则是调用了mapperProxyFactory的newInstance方法
mybatis源码学习之mybatis执行流程分析
MapperProxyFactory介绍

  • 在通过sqlSession获取Mapper时,其实先获取到的是这个工厂,然后通过这个工厂创建Mapper的动态代理类

MapperProxyFactory中的newInstance方法如下:
mybatis源码学习之mybatis执行流程分析

这里用到了动态代理,最后会调用MapperProxy中重写的的invoke方法
mybatis源码学习之mybatis执行流程分析
mybatis源码学习之mybatis执行流程分析

execute方法如下:
mybatis源码学习之mybatis执行流程分析

接着会调用executeForManay方法
mybatis源码学习之mybatis执行流程分析

selectList方法如下:
mybatis源码学习之mybatis执行流程分析

接着会执行exector中的query方法
mybatis源码学习之mybatis执行流程分析
mybatis源码学习之mybatis执行流程分析

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

可以看到最后使用的还是JDBC中的Statement,最后把查询到的结果返回查询流程就结束了。
mybatis源码学习之mybatis执行流程分析

下面mybatis总的一个处理流程:
mybatis源码学习之mybatis执行流程分析

mybatis一个大致的执行流程分析就到这里结束了,后面会继续详细讲解执行流程中涉及到的相关内容。文章来源地址https://www.toymoban.com/news/detail-471320.html

参考

  • Mybatis文档
  • mybatis学习视频

到了这里,关于mybatis源码学习之mybatis执行流程分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【源码解析】Mybatis执行原理

    MyBatis 是一款优秀的持久层框架,MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。 Mybatis中的mapper接口并没有具体实

    2024年02月16日
    浏览(33)
  • Mybatis源码(四)— 查询流程

    经过上一篇的getMapper方法的讲解之后getMapper解析。 此时Mybatis已经通过动态代理,创建了Dao的具体对象。因为其中MapperProxy实现了InvocationHandler,所以在执行具体的方法时,会执行MapperProxy中的invoke方法。 前几篇文章中已经解析到了getMapper方法,所以本篇会针对具体方法继续向

    2023年04月27日
    浏览(43)
  • 【Mybatis源码分析】Mybatis中的反射(MetaObject)详细讲解

    在使用Mybatis,编写DQL语句时,查询结果可能会是多个,多变量指定肯定是不现实的。而Mybatis可以进行映射,将JDBC返回的结果映射到实例类或者Map对象中,方便开发者直接使用返回对象,就可以得到从数据库取出来的结果。 映射原理大伙都知道是利用了反射(因为咱就只是通

    2023年04月08日
    浏览(76)
  • MyBatis底层源码分析

    🎄欢迎来到@边境矢梦°的csdn博文🎄 🎄本文主要梳理MyBatis底层源码分析 🎄 🌈我是边境矢梦°,一个正在为秋招和算法竞赛做准备的学生🌈 🎆喜欢的朋友可以关注一下 🫰🫰🫰 ,下次更新不迷路🎆 Ps: 月亮越亮说明知识点越重要 (重要性或者难度越大)🌑🌒🌓🌔🌕 

    2024年02月08日
    浏览(49)
  • MyBatis 源码分析(五):异常模块

    上一篇我们解了Mybatis解析器模块,本篇我们来了解反射模块。本文,我们来分享 MyBatis 的异常模块。 对应  exceptions  包,如下图所示: 在 MyBatis源码分析(二):项目结构 中,简单介绍了这个模块: 定义了 MyBatis 专有的 PersistenceException 和 TooManyResultsException 异常。 实际上

    2024年02月01日
    浏览(44)
  • MyBatis源码分析_ResultSetHandler(7)

    目录 1. 传统JDBC 2. Mybatis访问数据库 2.1  Statement访问数据库 2.2  火枪手 ResultSetHandler 出现 3. ResultSetHandler处理结果集 3.1 首先就是进入 handleResultSets 方法 3.2 handleResultSet 方法根据映射规则(resultMap)对结果集进行转化 3.3 handleRowValuesForSimpleResultMap 方法对行进行映射处理 4.  

    2024年02月15日
    浏览(46)
  • Mybatis源码分析_日志模块 (1)

    不得不承认,学习MyBatis的时间成本要比学习Spring低很多,Mybatis是我所了解过的代码量最小、整体架构最简单,但是又是最具有学习价值的一个框架。如果,你想快速的阅读一个框架的源码,并且掌握这个框架的精髓,那么Mybatis一定是你的首选。 在开始我们的源码阅读之前,

    2024年02月10日
    浏览(40)
  • MyBatis-Executor源码全面分析

    MyBatis版本-5.1.3 本篇文章主要分析MyBatis中执行器与插件的相关原理与源码。再分析源码之前,需要回顾一下基础的前置知识。 1. JDBC开发回顾 1.1 JDBC代码案例 Java DataBase Connectivity Java 数据库连接, Java语言操作数据库 JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型

    2024年02月12日
    浏览(44)
  • mybatis多参数传递报错问题分析+硬核mybatis底层源码分析+@Param注解+图文实战环境分析【4500字详解打通,没有比这更详细的了!】

    ❗操作 mybatis 时报错: org.apache.ibatis.binding.BindingException: Parameter ‘tableName’ not found. Available parameters are [arg1, arg0, param1, param2] Maven MySQL 8.0.30 在本机 MySQL 中执行: 🍀 pom.xml导入依赖 🍀 jdbc.properties 在 resources 目录下新建 jdbc.properties 配置文件。 🍀 mybatis-config.xml 在 resources 目

    2024年02月12日
    浏览(48)
  • Mybatis源码分析_Mapper接口是如何实例化的 (2)

    我们在使用Spring+mybatis的时候,经常都是直接写一个接口和一个对应的 ***Mapper.xml文件,然后业务代码就可以直接注入这个接口了。它是如何做到的呢? 接口: xml    想搞清楚这个问题,那还是要从Mybatis底层源码进行分析的。Mybatis是一个非常优先的框架,它大量的将所谓的

    2024年02月10日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包