一、mybatis分层图

二、运行流程

根据全局配置文件创建sqlSessionFactory对象

  1. 根据全局配置文件的io流来构建SqlSessionFactoryBuilder对象:
  2. 解析(XmlConfigBuilder遍历全局配置文件的每一项节点)全局配置文件里的每一个配置项;每一个配置项都会调用相应的方法进行初始化,之后将这些构建好的配置对象保存到Configuration中;这些配置对象执行的步骤以<resource mapper>为例:
  3. 根据resource解析的信息拿到mapper映射文件的地址,加载mapper映射文件的io流;
  4. 解析(XmlMapperBuilder遍历mapper映射文件的每一项节点),这些项返回的结果对象都会保存到Configuration里;以select|update这些标签为例:
  5. 通过statementParser解析这些标签内的每一项并将这些信息保存到mappedstatement对象,再将mappedstatement保存到Configuration
  6. 通过configuration对象构建defaultSqlSessionFactory对象

总结

  mybatis通过xpathparser(dom4j)将解析到的所有配置文件里的节点信息(生成相应的配置项对象)封装到configuration对象中,最终返回一个包含configuration的defaultSqlSessionFactory

根据sqlSessionFactory对象获取sqlsession对象

  1. 在openSessionFromDataSource()中通过先前构建DefaultSqlSessionFactory对象时传入的configuration属性获取环境信息
  2. 根据环境信息里的数据源、事务隔离级别等信息构建事务对象
  3. 根据事务、执行器类型创建对用的SQL类型执行器Executor(SIMPLE、REUSE、BATCH)
  4. 判断是否开启了二级缓存来对先前创建的执行器进行一次包装(这样开启了缓存每次我们再次查询都会先用cacheExecutor对象的方法,查询不到则通过包装进给他的Executor对象再次查询)
  5. 使用插件再对我们的executor进行包装。。。。
  6. 通过构建好的executor对象和configuration对象返回DefaultSqlSession

总结

  根据configuration获取环境信息创建事务对象,通过Transaction和ExecutorType创建Executor对象以及根据二级缓存、插件来进行多次包装,最终返回一个包含Executor和Configuration的DefaultSqlSession对象

根据sqlsession对象获取接口的代理对象(MapperProxy)

  1. 先前构建sqlSessionFactory时在configuration对象中有个mapperRegistry对象,这个对象中有个map,它以接口的地址(接口类型)作为key,value为MapperProxyFactory
  2. 从configuration中调用mapperRegistry的getMapper(type,sqlSession),通过type去查找map中的key,返回含有具体接口类型的MapperProxyFactory
  3. MapperProxy代理对象通过MapperProxyFactory传入当前的sqlSession进行创建并返回

执行增删改查方法

  1. getMapper()获取到的是mybatis为我们创建好的mapperProxy接口代理对象,invoke()会将我们的接口方法转为mybtis能识别的mapperMethod对象
  2. 首先判断方法的操作数据库类型(增删改查)、返回结果的数据结构,对参数进行重新包装(参考参数源码那一节),以查询对象为例:
  3. 调用sqlSession.one(),之后它还是会调用list();最终返回的对象从这个list集合里取第一个对象内容
  4. 调用executor.query(mappedStatement),从传入的mappedStatement中获取sql信息
  5. 判断session缓存是否有数据,没有就查询数据库
  6. 创建StatementHandler对象(preparedStatementHandler),根据插件进行包装
  7. 创建paramterHandler对象,根据插件进行包装
  8. 创建ResultSetHandler对象,根据插件进行包装
  9. 预编译sql产生PreparedStatement对象,调用paramterHandler设置参数(是通过TypeHander设置参数的)
  10. 执行查询后使用ResultSetHandler处理结果(通过TypeHander获取value)

封装参数

  MapperProxy(InvocationHandler动态代理)→invoke()→mybatis会将我们的接口方法转换成一个MapperMethod­.class,之后执行execute();

  首先判断标签类型,如果是查询判断方法返回类型,以返回一个对象为例:  method.convertArgsToSqlCommandParam(args)→paramNameResolver.getNamedParams(args)→ParamNameResolver【构造器初始化了我们参数的key,他会判断方法体上是否有@param的注解,如果有则会按照paramIndex:注解标注的值组成一个treeMap,如果没有则是paramIndex:map.size,在jdk1.8版本能够获取参数名】→getNamedParams(args)【如果没用@param标注&&参数就1个,通过args[names.firstKey()]返回;如果是多个,通过获取names.value作为key、names.key作为args[]的下标;并且mybatis额外为我们通过param+ String.valueOf(i + 1)作为key方式获取】。

  多参数下也就是说我们如果定义了@param(“”)的话就用定义的参数名取值;没定义的话则要用#{paramIndex?0}(视频里没说,看源码发现的)或者#{param1}(下标i+1了)

查询流程总结

  mybatis在初始化SqlSessionFactory对象的过程中,会为每个接口创建一个接口代理对象,并将这些信息保存在mapperRegistry(key是接口类型,value是接口代理对象工厂),之后在构建SqlSession中根据环境信息配置出事务对象,根据ExecutorType、事务隔离级别创建Executor,我们任何CRUD操作其实都是通过Executor去执行的;通过preparedStatementHandle创建preparedStatement(从mappedStatement获取到sql信息(key是namespace+methodId,value是每个标签内的所有信息)),而传入的参数和结果映射都是通过TypeHandler去设置的

总结

  1. 根据配置文件(全局,sql映射)初始化出Configuration对象
  2. 创建一个DefaultSqlSession对象,里面包含Configuration以及Executor(根据全局配置文件中的defaultExecutorType创建出对应的Executor)
  3. DefaultSqlSession.getMapper()拿到Mapper接口对应的MapperProxy
  4. MapperProxy里面有(DefaultSqlSession)
  5. 执行增删改查方法:
    • 调用DefaultSqlSession的增删改查(Executor)
    • 会创建一个StatementHandler对象(同时也会创建出ParameterHandler和ResultSetHandler)
    • 调用StatementHandler预编译SQL以及使用ParameterHandler来给sql设置参数值;
    • 调用StatementHandler的增删改查方法
    • ResultSetHandler封装结果
      注意:四大对象每个创建的时候都有一个interceptorChain.pluginAll(parameterHandler);

搞清楚每一步都做了什么工作,那么框架大致的流程及源码就了解的差不多了

Mybatis-运行原理的更多相关文章

  1. mybatis运行原理

    mybatis运行原理 运行过程中涉及到的类或者接口 Resources(c) :用于加载mybatis核心配置文件 XMLConfigBuilder(c) :用于解析xml文件(核心配置文件) Co ...

  2. 居然还有人这样解说mybatis运行原理

    目录 Mybatis基本认识 动态代理 JDK实现 CGLIB动态代理 总结 反射 Configuration对象作用 映射器结构 sqlsession执行流程(源码跟踪) Executor Stat ...

  3. JDBC介绍和Mybatis运行原理及事务处理

    本博客内容非自创,转载自以下三位,侵删: https://juejin.im/post/5ab7bd11f265da23906bfbc5 https://my.oschina.net/fifadxj/ ...

  4. mybatis运行原理学习

    一.分步骤分析 1.根据配置文件创建SqlSessionFactory: 解析文件的每一个信息保存在Configuration中,返回包含Configuration的DefaultSqlSession ...

  5. Mybatis的SqlSession运行原理

    前言 SqlSession是Mybatis最重要的构建之一,可以简单的认为Mybatis一系列的配置目的是生成类似 JDBC生成的Connection对象的SqlSession对象,这样才能与数据库开 ...

  6. 互联网轻量级框架SSM-查缺补漏第七天(MyBatis的解析和运行原理)

    第七章MyBatis的解析和运行原理 SqlSessionFactory是MyBatis的核心类之一,其最重要的功能就是提供创建MyBatis的核心借口SqlSession,所以要先创建SqlSess ...

  7. Mybatis的解析和运行原理

    Mybatis的解析和运行原理 Mybatis的运行过程大致分为两大步:第一步,读取配置文件缓存到Configuration对象,用以创建 SqlSessionFactory:第二步,SqlSessi ...

  8. Mybatis插件原理分析(二)

    在上一篇中Mybatis插件原理分析(一)中我们主要介绍了一下Mybatis插件相关的几个类的源码,并对源码进行了一些解释,接下来我们通过一个简单的插件实现来对Mybatis插件的运行流程进行分析. ...

  9. 【转】MaBatis学习---源码分析MyBatis缓存原理

    [原文]https://www.toutiao.com/i6594029178964673027/ 源码分析MyBatis缓存原理 1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 ...

  10. 深入理解MyBatis的原理:整个体系

    前言:工作中虽然用到了 MyBatis,可完全不知道为什么,再不学习就晚了,这里将记录我的学习笔记,整个 MyBatis 的体系. 一.简介 1.传统的JDBC JDBC 是一种典型的桥接模式. 使用 ...

随机推荐

  1. Java学习笔记:GUI基础

    一:我们使用到的java GUI的API可以分为3种类: 组件类(component class) 容器类(container class) 辅助类(helper class) 1:组件类:组件类是用 ...

  2. 前端调试工具(DevTools)

    前端调试工具(DevTools) 开启:F12 布局 切换PC和移动端 页面元素的快速测试技巧 保持元素的hover等状态:选中当前行点击右键 元素状态改变的监控技巧 触发断点后元素状态不会再改变,可 ...

  3. vue配置请求拦截器和响应拦截器

    首先确保我们已经设置的store.js进行值的存取,这时候我们需要配置请求和响应的拦截器设置 main.js import Vue from 'vue' import App from './App' ...

  4. 关于Python中用户输入字符串(与变量名相同)无法作为变量名引用的理解以及解决方案

    在用户登录账号时,我需要在字典中查找是否存在其账号名称以及密码是否正确. 所以,我想将用户输入的账号赋值给变量,在字典中查找是否有此指值. 代码如下: 1 Ya = {'姓名': 'Ya', 'pas ...

  5. C#简单配置类及数据绑定

    目录 简介 配置基类 派生配置类 数据绑定 Winform中的数据绑定 WPF下的数据绑定 附件 简介 本文实现一个简单的配置类,原理比较简单,适用于一些小型项目.主要实现以下功能: 保存配置到jso ...

  6. 普通邮箱设置客户端授权码并开启stmp服务以及关于QQ邮箱“命令顺序不正确。 服务器响应为:Error: need EHLO and AUTH first !”问题全指导

    Zoomla!逐浪CMS带有强大的邮局功能,可以用于发送邮件与进行事务管理. 其中邮局配置大家不太熟悉这里提供一系列教程. 1.首先在QQ邮箱当中开启"POP3/SMTP服务" 2 ...

  7. 简易发号SQL,可用于生成指定前缀自增序列--改进版

    使用merge语法实现新增or更新 首先创建表 CREATE TABLE Test.dbo.Increments ( Prefix varchar(50) NOT NULL, [MaxNum ] bi ...

  8. 推荐一款颜值逆天且功能齐全的开源Shell工具!

    前言 以前在windows上一直使用的SSH工具是XShell,后来转到mac平台,XShell没有mac版本.所以之前一直在找一款颜值高,功能齐全的可以作为日常使用的Shell工具. 我知道mac下 ...

  9. gitee+typro+picgo搭建博客图床

    gitee+typro+picgo搭建博客图床 前提环境 typro.picgo.nodejs 直接在官网下载即可 下载完成后,打开picgo 安装插件gitee-uploader 1.1-2即可显示 ...

  10. springboot静态工具类bean的注入

    工具类中调用数据.但是由于工具类方法一般都写成static,所以直接注入就存在问题. 所以写成了这样: package com.rm.framework.core; import org.spring ...