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. 001、nodelocaldns(/etc/resolv.conf)

    nodelocaldns  pod 中的 /etc/resolv.conf 虽然读取的是 宿主机的/etc/resolv.conf,但是不是实时同步更新的.可能同步更新会有延迟 所以如果  /etc/ ...

  2. postman连接mysql数据库

    转载:https://www.cnblogs.com/pengxiaojie/p/13495237.html 1.安装 2.启动服务 3.执行sql语句 安装: 想要postman连接mysql,需要 ...

  3. python连接数据库系列

    1.Python连接MySQL 具体详情参考:MySQL笔记 Python连接MySQL需要借助pymysql,安装pymysql pip install pymysql 1.1 pymysql连接数 ...

  4. go语言 cmd执行命令,遇到空格或者双引号无法执行成功的解决方案

    大部分go执行cmd命令都是,我也是这样写的 package main import ( "fmt" "os/exec" ) func main() { cmd ...

  5. 078_Sublime HaoIDE 搭建 Lightning Aura环境

    随着 Classic 不断的向 1 .HaoIDE->Setting->User Setting 请把以下内容copy进去,修改账号密码token以及项目名称,例子中列举了两个Projec ...

  6. ssgvip设置

    ssgvip.tpl set service "{vipport}" protocol {xieyi} src-port 0-65535 dst-port {vipport}-{v ...

  7. Log4net使用探究

    第一步: 通过Nuget package 搜索Apache Log4net安装 第二步: 在项目Global.asax文件中添加读取 配置文件 第三步: 编写Loghelper 文件 1 public ...

  8. Ubuntu截图软件

    Ubuntu截图软件 方法一:使用系统自带的快捷键 可以将其修改为自己习惯的快捷键 如图: 方式二:使用软件ksnip GitHub: https://github.com/ksnip/ksnip 安 ...

  9. 路飞之-后台日志封装-前后端分离的rbac项目演示-全局异常处理封装-封装Response-luffy数据库创建-软件开发模式-User模块用户表-django的配置文件-开启media访问

    目录 路飞之-后台日志封装-前后端分离的rbac项目演示-全局异常处理封装-封装Response-luffy数据库创建-软件开发模式-User模块用户表-django的配置文件-开启media访问 今 ...

  10. 若依分离版本+Nginx+docker+jenkins 部署

    准备: jenkins node.js 若依前后分离 docker 最终访问地址: 服务端api地址:192.168.66.74:8086 前端页面地址:192.168.66.61:7001 jenk ...