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原理探究的更多相关文章

  1. 《深入理解mybatis原理》 MyBatis的架构设计以及实例分析

    作者博客:http://blog.csdn.net/u010349169/article/category/2309433 MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简 ...

  2. 《深入理解mybatis原理1》 MyBatis的架构设计以及实例分析

    <深入理解mybatis原理> MyBatis的架构设计以及实例分析 MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简单.优雅.本文主要讲述MyBatis的架构 ...

  3. [原] KVM 虚拟化原理探究(1)— overview

    KVM 虚拟化原理探究- overview 标签(空格分隔): KVM 写在前面的话 本文不介绍kvm和qemu的基本安装操作,希望读者具有一定的KVM实践经验.同时希望借此系列博客,能够对KVM底层 ...

  4. [原] KVM 虚拟化原理探究 —— 目录

    KVM 虚拟化原理探究 -- 目录 标签(空格分隔): KVM KVM 虚拟化原理探究(1)- overview KVM 虚拟化原理探究(2)- QEMU启动过程 KVM 虚拟化原理探究(3)- CP ...

  5. [原] KVM 虚拟化原理探究(6)— 块设备IO虚拟化

    KVM 虚拟化原理探究(6)- 块设备IO虚拟化 标签(空格分隔): KVM [toc] 块设备IO虚拟化简介 上一篇文章讲到了网络IO虚拟化,作为另外一个重要的虚拟化资源,块设备IO的虚拟化也是同样 ...

  6. [原] KVM 虚拟化原理探究(5)— 网络IO虚拟化

    KVM 虚拟化原理探究(5)- 网络IO虚拟化 标签(空格分隔): KVM IO 虚拟化简介 前面的文章介绍了KVM的启动过程,CPU虚拟化,内存虚拟化原理.作为一个完整的风诺依曼计算机系统,必然有输 ...

  7. [原] KVM 虚拟化原理探究(4)— 内存虚拟化

    KVM 虚拟化原理探究(4)- 内存虚拟化 标签(空格分隔): KVM 内存虚拟化简介 前一章介绍了CPU虚拟化的内容,这一章介绍一下KVM的内存虚拟化原理.可以说内存是除了CPU外最重要的组件,Gu ...

  8. [原] KVM 虚拟化原理探究(3)— CPU 虚拟化

    KVM 虚拟化原理探究(3)- CPU 虚拟化 标签(空格分隔): KVM [TOC] CPU 虚拟化简介 上一篇文章笼统的介绍了一个虚拟机的诞生过程,从demo中也可以看到,运行一个虚拟机再也不需要 ...

  9. [原] KVM 虚拟化原理探究(2)— QEMU启动过程

    KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...

  10. 弱类型变量原理探究(转载 http://www.csdn.net/article/2014-09-15/2821685-exploring-of-the-php)

    N首页> 云计算 [问底]王帅:深入PHP内核(一)——弱类型变量原理探究 发表于2014-09-19 09:00| 13055次阅读| 来源CSDN| 36 条评论| 作者王帅 问底PHP王帅 ...

随机推荐

  1. C语言联合体(共用体)使用方法及大小计算

    作者的话 本文介绍联合体的定义.如何使用联合体,包括联合体的声明.联合体变量创建.联合体内存使用,以及联合体大小的计算,最后附上用联合体判断当前环境是大端还是小端的方法. 联合体的定义 联合体,又叫共 ...

  2. PHP常见方法封装

    1.get请求 function get_curl($url, $timeout = 5) { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$url) ...

  3. Mac的Dock栏是什么?Mac Dock栏使用技巧

    ​ Dock栏就是Mac电脑屏幕下方的那一排快捷键,我们可以把自己常用的程序放到Dock上面,这样可以帮助我们快速的打开自己想要打开的文件和程序,默认情况下,OS X 的 Dock 置于屏幕的底部.当 ...

  4. Launchpad是什么?Launchpad使用教程

    ​ Launchpad是什么?Launchpad 是用来查找和打开Mac系统下的 app 的最快捷方式,通过 Launchpad,您可以查看.整理并轻松打开Mac里面几乎所有的应用软件.下面带来Mac ...

  5. div里元素横向排列 居中对齐

      <div>             <img src="//s.weituibao.com/1582958061265/mlogo.png" alt=&quo ...

  6. RestTemplate 设置超时时间

    不废话直接上代码 SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); reque ...

  7. 15、java递归解决迷宫问题

    递归真是一个.看着简单,听着简单,写不出来,想不到.以前也不是不理解递归,也不是看不懂递归的代码,但说实话真的很难想到自己去用这个递归也很难理清楚这个递归到底从哪里开始到哪里结束,将哪个步骤作为 一个 ...

  8. 关于MYSQL知识点复习

    关于MYSQL关联查询JOIN:   https://www.cnblogs.com/withscorpion/p/9454490.html

  9. HBase建命名空间建表

    public class HBaseDDL { //声明一个静态属性 static public Connection conn = HBaseConnection2.conn; /** * 创建命名 ...

  10. selenium+python的网站爬虫

    爬取网站听起来就是程序员的标配,之前一直没有时间学一下,最近有空学习一下顺便记录一下 爬取网站实际上就是利用计算机模拟人的操作来对网站的前端进行访问,而各大浏览器也给计算机提供了访问的接口,也就是浏览 ...