mybatis原理探究
jdbc数据库运行流程:

JDBC有哪三种statement接口:
Statement
1、Statement接口提供了执行语句和获取结果的基本方法; 2、Statement继承自Wrapper;3、普通的不带参的查询SQL;支持批量更新,批量删除;
4、Statement每次执行sql语句,数据库都要执行sql语句的编译 ,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement。
PreparedStatement
1、PreparedStatement接口添加了处理 IN 参数的方法; 2、PreparedStatement继承自Statement;3、可变参数的SQL,编译一次,执行多次,效率高; 4、安全性好,有效防止Sql注入等问题; 5、支持批量更新,批量删除; 6. 在执行可变参数的一条SQL时,PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。 7 对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch; 8. 代码的可读性和可维护性。
CallableStatement
1、CallableStatement接口添加了处理 OUT 参数的方法。2、继承自PreparedStatement,支持带参数的SQL操作; 3、支持调用存储过程,提供了对输出和输入/输出参数(INOUT)的支持;
Mybatis整体流程:

1. mybatis配置文件:SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。Mapper.xml为mybatis的sql映射文件,配置了操作数据库的sql语句,该文件在SqlMapConfig.xml中加载。
2. SqlSessionFactory:通过mybatis环境等配置信息构造SqlSessionFactory,即会话工厂。
3. sqlSession:通过会话工厂创建sqlSession即会话,程序员通过sqlsession会话接口对数据库进行增删改查操作。
4. Executor执行器:mybatis底层自定义了Executor执行器接口来具体操作数据库,Executor接口有两个实现,1个是基本执行器(默认)、另一个是缓存执行器,sqlsession底层是通过executor接口操作数据库的。
5. Mapped Statement:它也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中1个select\insert\update\delete标签对应1个Mapped Statement对象,select\insert\update\delete标签的id即是Mapped statement的id。
- Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射到sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
- Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程
sqlSessionFactory创建流程:
对应的动作:SqlSessionFactoryBuilder().build;
SqlSessionFactoryBuilder:利用建造者的身份提供多个创建sqlSessionFactory的方法,总体上分为两种,根据字符流创建与根据字节流创建。但是归根结底还是由XMLConfigBuilder来完成具体的工作。
XMLConfigBuilder:专门来解析全局配置文件的解析器
1 解析</properties>标签
2 解析</settings>标签
3 解析</typeAliases>标签
4 解析</plugins>标签
5 解析</environments>标签
6 解析</mappers>标签
XMLMapperBuilder:从映射文件中的<mapper>根标签开始解析,直到完整的解析完毕
1 获取<mapper>标签的namespace值,也就是命名空间
2 解析<cache-ref>子标签
3 解析<cache>子标签
4 解析<parameterMap>子标签
5 解析<resultMap>子标签
6 解析<sql>子标签,也就是SQL片段 XPATH
7 解析<select>\<insert>\<update>\<delete>子标签 创建MappedStatement对象 由XmlStatementBuilder具体完成
8 创建MapperProxy并与namespace绑定
XmlStatementBuilder:
1 获取statement的id属性(特别关键的值)
2 获取入参类型
3 别名处理,获取入参对应的Java类型
4 获取ResultMap
5 别名处理,获取返回值对应的Java类型
6 设置默认StatementType为Prepared,该参数指定了后面的JDBC处理时,采用哪种Statement
7 解析SQL命令类型是什么?确定操作是CRUD中的哪一种
8 是否查询语句,决定是否用缓存
9 创建SqlSource,解析SQL,封装SQL语句(未参数绑定)和入参信息。由XMLScriptBuilder具体完成
10 通过构建者助手,创建MappedStatement对象
XMLScriptBuilder:
1 创建SqlSource、
2 初始化动态SQL中的节点处理器XMLScriptBuilder、
3 解析select\insert\ update\delete标签中的SQL语句,最终将解析到的SqlNode封装到MixedSqlNode中的List集合中,
将带有${}号的SQL信息封装到TextSqlNode,将带有#{}号的SQL信息封装到StaticTextSqlNode
将动态SQL标签中的SQL信息分别封装到不同的SqlNode中
4 如果SQL中包含${}和动态SQL语句,则将SqlNode封装到DynamicSqlSource
5 如果SQL中包含#{},则将SqlNode封装到RawSqlSource中,最后将解析之后的SQL信息,封装到StaticSqlSource

SqlSession创建流程:
对应的动作:sqlSessionFactory().openSession
1 从configuration中获取数据源环境信息environment
2 根据environment获取事务工厂TransactionFactory
3 通过TransactionFactory创建JdbcTransaction或者ManagedTransaction实例 tx
4 创建Executor执行器【批处理执行器、可重用执行器、简单执行器、使用缓存执行器】,具体创建那个哪种执行器根据执行类型来决定. 其中缓存执行器通过批处理执行器、可重用执行器、简单执行器中的一个通过组合模式来实现.
5 创建DefaultSqlSession
Mapper代理创建流程:
对应的动作:sqlsession.getMapper
sqlsession.getMapper >> configuration.getMapper >> mapperRegistry.getMapper, 随后根据Mapper接口的类型,从mapperRegistry该类的knownMappers这一Map集合中获取Mapper代理对象工厂MapperProxyFactory
通过MapperProxyFactory的newInstance方法, 其内部通过如下方法:
new MapperProxy<>(sqlSession, mapperInterface, methodCache);
创建了一个mapperProxy(InvocationHandler的实现类), 最后通过Proxy的如下方法:
Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
创建基于JDK实现的MapperProxy
Mapper代理执行流程(以defaultSqlSession执行select接口为例)
0 执行代理的invoke方法,进而通过DefaultSqlSession执行sql语句
1 根据传入的statementId,获取MappedStatement对象
2 创建缓存key
3 从一级缓存中获取数据,如果一级缓存没有数据,则从数据库查询数据
4 创建RoutingStatementHandler,并在RoutingStatementHandler类中初始化delegate类(SimpleStatementHandler、PreparedStatementHandler)
5 通过StatementHandler创建sql连接、创建Statement(PreparedStatement、Statement、CallableStatement),并调用自身的parameterize方法对statement设置参数
6 执行SQL语句(已经设置过参数),并且映射结果

DefaultParameterHandler的setParameters将动态sql中的?替换为传入的参数
SQL查询语句的执行是由SqlSession分发交由Executor托管执行,调度StatementHandler负责JDBCstatement操作,之后下发给ParameterHandler负责对用户传递参数进行转化处理SQL参数,再接着执行SQL语句,最后通过ResultSetHandler对返回结果进行封装处理返回。
mybatis原理探究的更多相关文章
- 《深入理解mybatis原理》 MyBatis的架构设计以及实例分析
作者博客:http://blog.csdn.net/u010349169/article/category/2309433 MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简 ...
- 《深入理解mybatis原理1》 MyBatis的架构设计以及实例分析
<深入理解mybatis原理> MyBatis的架构设计以及实例分析 MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简单.优雅.本文主要讲述MyBatis的架构 ...
- [原] KVM 虚拟化原理探究(1)— overview
KVM 虚拟化原理探究- overview 标签(空格分隔): KVM 写在前面的话 本文不介绍kvm和qemu的基本安装操作,希望读者具有一定的KVM实践经验.同时希望借此系列博客,能够对KVM底层 ...
- [原] KVM 虚拟化原理探究 —— 目录
KVM 虚拟化原理探究 -- 目录 标签(空格分隔): KVM KVM 虚拟化原理探究(1)- overview KVM 虚拟化原理探究(2)- QEMU启动过程 KVM 虚拟化原理探究(3)- CP ...
- [原] KVM 虚拟化原理探究(6)— 块设备IO虚拟化
KVM 虚拟化原理探究(6)- 块设备IO虚拟化 标签(空格分隔): KVM [toc] 块设备IO虚拟化简介 上一篇文章讲到了网络IO虚拟化,作为另外一个重要的虚拟化资源,块设备IO的虚拟化也是同样 ...
- [原] KVM 虚拟化原理探究(5)— 网络IO虚拟化
KVM 虚拟化原理探究(5)- 网络IO虚拟化 标签(空格分隔): KVM IO 虚拟化简介 前面的文章介绍了KVM的启动过程,CPU虚拟化,内存虚拟化原理.作为一个完整的风诺依曼计算机系统,必然有输 ...
- [原] KVM 虚拟化原理探究(4)— 内存虚拟化
KVM 虚拟化原理探究(4)- 内存虚拟化 标签(空格分隔): KVM 内存虚拟化简介 前一章介绍了CPU虚拟化的内容,这一章介绍一下KVM的内存虚拟化原理.可以说内存是除了CPU外最重要的组件,Gu ...
- [原] KVM 虚拟化原理探究(3)— CPU 虚拟化
KVM 虚拟化原理探究(3)- CPU 虚拟化 标签(空格分隔): KVM [TOC] CPU 虚拟化简介 上一篇文章笼统的介绍了一个虚拟机的诞生过程,从demo中也可以看到,运行一个虚拟机再也不需要 ...
- [原] KVM 虚拟化原理探究(2)— QEMU启动过程
KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...
- 弱类型变量原理探究(转载 http://www.csdn.net/article/2014-09-15/2821685-exploring-of-the-php)
N首页> 云计算 [问底]王帅:深入PHP内核(一)——弱类型变量原理探究 发表于2014-09-19 09:00| 13055次阅读| 来源CSDN| 36 条评论| 作者王帅 问底PHP王帅 ...
随机推荐
- Deer_GF之【AssetsHotfix】和【AssetsNative】文件夹的区别
Hi,今天介绍一下Deer_Gf里的[AssetsHotfix]和[AssetsNative]文件夹的区别: 框架介绍请移步[Deer_GF之框架介绍] 一.[AssetsHotfix] ...
- 每次 git 都需要输入用户名和密码的解决办法
git config --global credential.helper store git pull /git push (第一次输入,下次就不用再次输入数据)
- PHP压缩二进制流转CSV文件
接口返回的数据是二进制流,需先BASE64解码,再进行解压缩,压缩的文件格式为ZIP,需使用Inflater进行解压,即可得到文件. java demo: 转成PHP代码: 贴上 原始二进制流数据,需 ...
- centos系统时间与硬件时间不一致
centos系统时间与硬件时间设置.同步 将系统时间设置成2018年7月31日 12:00:00 date -s "07/31/18 12:00:00" hwclock -s 将 ...
- UE4大地图(流关卡、无缝地图)
原作者:xiaosongfang 对于UE4来说我只是个菜鸟,研究一下网上的教程稍微尝试的做一下demo,所以可能下面会有描述不准确或者说没解释清的地方请多谅解哈.也非常欢迎指出我说的不对的地方一起学 ...
- win10系统IE浏览器打不开 点击无反应 解决办法
打开左下角开始菜单 步骤阅读 2 点击右边的Cortana,在下面的输入框中输入:regedit,等待它自动搜索出来后,以管理员身份打开这个注册表编辑器:当然熟悉电脑的同学可以直接打开运行----re ...
- IC杂记
BNF(Backus-Naur Form) 巴科斯范式, 以美国人巴科斯(Backus)和丹麦人诺尔(Naur)的名字命名的一种形式化的语法表示方法,用来描述语法的一种形式体系,是一种典型的元语言.又 ...
- docker 安装mongodb
一.安装mongodb 我们首先改一下镜像源,避免拉去速度太慢 创建daemon.json文件:位于/etc/docker目录下: 登录阿里云 即可 2.docker 搜索mongo镜像 然后pull ...
- 【Pr】如何将音频剪成多段批量导出
如何将音频剪成多段批量导出 需要软件: Pr, Adobe Media Encoder (时间线窗口中) 用剃刀将音频割成多段 (时间线窗口中) 选中音频右键 | 嵌套 | 输入名字 (嵌套快捷键:A ...
- Asp.Net Core上传大文件请求体限制设置
IIS进程内部署时 1. Web.Config的<system.webServer>节点下增加 <security> <requestFiltering> < ...