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

news/2024/11/23 20:58:35/

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对象
在这里插入图片描述

2、parse方法则是调用了XPath对象的evalNode方法对配置文件中的configuration节点进行解析,会把节点内容放在XNode对象中然后返回;
在这里插入图片描述

3、parseConfiguration方法会对configuration节点解析出来的内容再进行解析,会把解析出来的内容放在configuration对象中;实际上配置文件中的内容解析出来后都会存到Configuration中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YjYs8014-1685886063612)(Pasted%20image%2020230223222648.png)]

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 firstpropertiesElement(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 #631environmentsElement(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.knownMappers2.*/mapperElement(root.evalNode("mappers"));

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

获取SqlSession

调用openSession()方法获取SqlSession

在这里插入图片描述

创建Executor的对象,这里会根据类型去创建对应的Executor
在这里插入图片描述

最后一行的代码:interceptorChain.pluginAll(executor)的作用是会调用所有拦截器对象的plugin方法


最后执行到Plugin类的wrap方法对executor进行包装

执行getMapper方法

实际上调用的是configuration对象的getMapper方法
在这里插入图片描述

而configuration对象则是调用了mapperRegistry对象的getMapper方法;
在这里插入图片描述

MapperRegistry简介

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

接着往下看;mapperRegistry的getMapper方法则是调用了mapperProxyFactory的newInstance方法
在这里插入图片描述
MapperProxyFactory介绍

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

MapperProxyFactory中的newInstance方法如下:
在这里插入图片描述

这里用到了动态代理,最后会调用MapperProxy中重写的的invoke方法
在这里插入图片描述
在这里插入图片描述

execute方法如下:
在这里插入图片描述

接着会调用executeForManay方法
在这里插入图片描述

selectList方法如下:
在这里插入图片描述

接着会执行exector中的query方法
在这里插入图片描述
在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6lTPACoy-1685886501778)(Pasted%20image%2020230321214105.png)]

可以看到最后使用的还是JDBC中的Statement,最后把查询到的结果返回查询流程就结束了。
在这里插入图片描述

下面mybatis总的一个处理流程:
在这里插入图片描述

mybatis一个大致的执行流程分析就到这里结束了,后面会继续详细讲解执行流程中涉及到的相关内容。

参考

  • Mybatis文档
  • mybatis学习视频

http://www.ppmy.cn/news/211453.html

相关文章

toadb 数据库基础架构

系列文章目录 第一章 toadb 数据库基础架构 ​​​​​​​​​​​​​​第二章 toadb 词法/语法分析器基础 【保姆级教程】​​​​​​​ 目录 系列文章目录 关键词 概述 概念 作用

麦肯锡的逻辑思考力(读后感)---前言

本书能够帮助你掌握有益于工作的逻辑思维。 理科读者或许会认为“我擅长逻辑思维”&#xff0c;所以选了理科&#xff0c;并且从事了与逻辑相关的工作。但是你错了&#xff0c;你并非因为擅长逻辑思维才选择理科&#xff0c;而是因为擅长数学类科目&#xff0c;才选择了理科。 …

后阿里巴巴时代:从消费资本化理论“望远镜”中探视——电子商务发展趋势探析之一...

&#xff08;本文首发于《上海信息化》&#xff09;2008年第4期&#xff0c;大、小标题稍有改动&#xff09; 在当前众多的电子商务应用服务商中&#xff0c;作为大宗产品的网上交易平台&#xff0c;金银岛网交所率先采用了一种全新的B2B业务模式。其为了进一步保障企业用户营销…

后阿里巴巴时代:从消费资本化理论“望远镜”中探视——电子商务发展趋势探析之一

&#xff08;本文首发于《上海信息化》&#xff09;2008年第4期&#xff0c;大、小标题稍有改动&#xff09; 在当前众多的电子商务应用服务商中&#xff0c;作为大宗产品的网上交易平台&#xff0c;金银岛网交所率先采用了一种全新的B2B业务模式。其为了进一步保障企业用户营销…

2022-2028全球与中国数码激光遥测仪市场现状及未来发展趋势

2021年全球数码激光遥测仪市场销售额达到了 亿美元&#xff0c;预计2028年将达到 亿美元&#xff0c;年复合增长率&#xff08;CAGR&#xff09;为 %&#xff08;2022-2028&#xff09;。地区层面来看&#xff0c;中国市场在过去几年变化较快&#xff0c;2021年市场规模为 百万…

分镜头剧本模板、故事图模板

说明 镜号&#xff1a;每个镜头按顺序的编号  景别&#xff1a;一般分为全景、中景、近景、特写和显微等  技巧&#xff1a;包括镜头的运用—推、拉、摇、移、跟等&#xff0c;镜头的组合—淡出谈入、切换、叠化等。  画面&#xff1a;详细写出画面里场景的内容和变化&…

食品品牌如何做好消费需求洞察直抵消费者心智

做生意的都明白这样一个道理&#xff1a;“先找到买主&#xff0c;再依照需求出售”。之所以这一点很重要&#xff0c;因为这揭示了一条经营企业过程中必须遵守的金科玉律&#xff1a;先有需求&#xff0c;而后才有你的品牌、服务或功能。 需求洞察是品牌、产品、服务等一切的…

越来越热的眼镜,苹果为什么不做 | 今夜科技谈

NEW 关注Tech逆向思维视频号 最新视频→【摆脱焦虑告别烦恼&#xff0c;家装变局让消费者更从容】 出品&#xff5c;极客公园 文&#xff5c;李楠 01 01苹果发布会&#xff1a;「十三」香不香&#xff0c;眼镜为何没来&#xff1f; 用一个词来形容苹果这次的发布会&#xff0c;…