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对返回结果进行封装处理返回。

最新文章

  1. 【原】Github系列之一:一起做仿天气类应用中的实时模糊效果LiveBlur
  2. css回忆(一)
  3. mysql多表查询例子
  4. 记一次Web应用CPU偏高
  5. artDialog 文档
  6. Advanced Packaging Tool
  7. 甲骨文推出MySQL Fabric,简化MySQL的高可用性与可扩展性
  8. php实现网页标签补全方法(转)
  9. SRM 581 D2 L3:TreeUnionDiv2,Floyd算法
  10. 获取android源码中遇到的问题
  11. 【一天一道LeetCode】#86. Partition List
  12. ES6随手学
  13. 05 - json转成树状结构
  14. CCF CSP 201403-1 相反数
  15. python并发编程基础之守护进程、队列、锁
  16. Git更新远程仓库代码到本地(转)
  17. mysql-数据库管理安装
  18. 输出cglib以及jdk动态代理产生的class文件
  19. jquery中filter的用法
  20. springbootf访问静态文件资源

热门文章

  1. K8s集群版本升级
  2. vue 利用xlsx、xlsx-style、file-saver实现前端导出excel表格 (包括设置单元格居中、边框等样式) antdesignvue、elementui、vxetable 等都适用
  3. 只会Jquery,后端程序员如何学会前端(webpack,react,babel,es5,es6)
  4. WebAPI例子
  5. VOLO论文笔记
  6. 图片在div中居中
  7. java8线程池创建并使用
  8. shell语法6-exit命令、文件重定向、引入外部脚本
  9. es实现规格分组分析
  10. 直播带货源码,flutter 顶部滚动栏+页面