mybatis流程具象化知识学习笔记
2022-11-17 10:11:31 0 举报
AI智能生成
登录查看完整内容
mybatis流程具象化知识学习笔记
作者其他创作
大纲/内容
工厂建造工人
创建工厂
SqlSessionFactoryBuilder
小箱子
Configuration
管子生产工厂
生产管子
sqlSessionFactory
管子
SqlSession
智能开关
设置水流大小
Executor
水流形状转化器(入口)
StatementHandler
出口形状转换
ResultSetHandler
mybatis流程具象化
SqlSource
resultmap
MappedStatement
ParameterHandler
TypeHandler
全流程顺序
查询缓存工厂建造者
配置
查询缓存工厂
会话工厂
查询缓存
执行者
声明处理程序
声明管理者
结果集处理程序
mybatis流程具象化_测试
管子水流工厂简版
水流管子工厂放水事件
MyBatis框架主要完成的是以下2件事情: 根据JDBC规范建立与数据库的连接。 通过反射打通Java对象与数据库参数交互之间相互转换的关系。
简介
第一个是跟客户打交道的服务员,它是用来接收程序的工作指令的,我们把它叫做接口层。
第二个是后台的厨师,他们根据客户的点菜单,把原材料加工成成品,然后传到窗口。这一层是真正去操作数据的,我们把它叫做核心层。
最后就是餐厅也需要有人做后勤(比如清洁、采购、财务),来支持厨师的工作和整个餐厅的运营。我们把它叫做基础层。
餐厅的服务流程
接口Class对象是大内太监,里面的方法和字段比做他的一身武艺,但是他没有小DD(构造器),
那怎么办呢?
所以不能new实例。一身武艺后继无人。
写一个类,实现该接口。这个就相当于大街上拉了一个人,认他做干爹。一身武艺传给他,只是比他干爹多了小DD,可以new实例。
正常途径(implements)
通过妙手圣医Proxy的克隆大法(Proxy.getProxyClass())克隆一个Class,但是有小DD。所以这个克隆人Class可以创建实例,也就是代理对象。
代理Class其实就是附有构造器的接口Class,一样的类结构信息,却能创建实例。
非正常途径(动态代理):
太监
动态代理
比喻
组合模式
比如MyBatis对动态SQL的解析
特殊
初始化阶段:读取XML配置文件和注解中的配置信息,创建解析对象,并完成各个模块的初始化工作。就是把我们的配置文件加载到内存里面去。在sqlSession初始化的时候加载到内存中去的。
代理阶段:封装iBatis的编程模型,使用mapper接口开发的初始化工作;
数据读写阶段:通过SqlSession完成SQL的解析,参数的映射,SQL的执行,结果的反射解析过程。
阶段
创建SqlSessionFactory实例
实例化过程中,加载配置文件创建configuration对象
通过factory创建SqlSession
通过SqlSession获取mapper接口动态代理
动态代理回调sqlsession中某查询方法
SqlSession将查询方法转发给Executor
Executor基于JDBC访问数据库获取数据
Executor通过反射将数据转换成POJO并返回;给SqlSession
将数据返回给调用者
MyBatis的设计思路
简述
首先接口层是我们打交道最多的。核心对象是SqlSession,它是上层应用和MyBatis打交道的桥梁,SqlSession 上定义了非常多的对数据库的操作方法。接口层在接收到调用请求的时候,会调用核心处理层的相应模块来完成具体的数据库操作。
这是传统的传递Statement Id 和查询参数给 SqlSession 对象,使用 SqlSession对象完成和数据库的交互;MyBatis 提供了非常方便和简单的API,供用户实现对数据库的增删改查数据操作,以及对数据库连接信息和MyBatis 自身配置信息的维护操作
上述使用MyBatis 的方法,是创建一个和数据库打交道的SqlSession对象,然后根据Statement Id 和参数来操作数据库,这种方式固然很简单和实用,但是它不符合面向对象语言的概念和面向接口编程的编程习惯。由于面向接口的编程是面向对象的大趋势,MyBatis 为了适应这一趋势,增加了第二种使用MyBatis 支持接口(Interface)调用方式。
a.使用传统的MyBatis提供的API;
MyBatis 将配置文件中的每一个 节点抽象为一个 Mapper 接口,而这个接口中声明的方法和跟 节点中的 节点项对应,即 节点的id值为Mapper 接口中的方法名称,parameterType 值表示Mapper 对应方法的入参类型,而resultMap 值则对应了Mapper 接口表示的返回值类型或者返回结果集的元素类型。
MyBatis 引用Mapper 接口这种调用方式,纯粹是为了满足面向接口编程的需要。(其实还有一个原因是在于,面向接口的编程,使得用户在接口上可以使用注解来配置SQL语句,这样就可以脱离XML配置文件,实现“0配置”
b. 使用Mapper接口
两种方式
接口层
接下来是核心处理层。既然叫核心处理层,也就是跟数据库操作相关的动作都是在这一层完成的。核心处理层主要做了这几件事
插件也属于核心层,这是由它的工作方式和拦截的对象决定的。
a. 通过传入参数构建动态SQL语句;
b. SQL语句的执行以及封装查询结果集成List
主要功能
内容
把接口中传入的参数解析并且映射成JDBC 类型;
解析xml 文件中的SQL 语句,包括插入参数,和动态SQL 的生成;
执行SQL 语句;
处理结果集,并映射成Java 对象。
步骤
核心处理层
最后一个就是基础支持层。基础支持层主要是一些抽取出来的通用的功能(实现复用),用来支持核心处理层的功能。比如数据源、缓存(请点击跳转至缓存详解)、日志、xml 解析、反射、IO、事务等等这些功能。
3.1. 事务管理机制
3.2. 连接池管理机制
3.3. 缓存机制
传统的MyBatis 配置SQL 语句方式就是使用XML文件进行配置的,但是这种方式不能很好地支持面向接口编程的理念,为了支持面向接口的编程,MyBatis 引入了Mapper接口的概念,面向接口的引入,对使用注解来配置SQL 语句成为可能,用户只需要在接口上添加必要的注解即可,不用再去配置XML文件了,但是,目前的MyBatis 只是对注解配置SQL 语句提供了有限的支持,某些高级功能还是要依赖XML配置文件配置SQL 语句。
3. 4. SQL语句的配置方式
3大机制和sql配置
通过建造者模式创建一个工厂类,定位,加载,解析配置文件的就是在这一步完成的,包括mybatis-config.xml 和Mapper 适配器文件。
通过SqlSessionFactory 创建一个SqlSession。
获得Mapper 对象。
基础支持层
分层
通过SqlSessionFactoryBuilder 解析mybatis-config.xml 文件中的 Configuration 创建一个 sqlSessionFactory
MyBatis所有的配置信息都维持在Configuration对象之中。
通过sqlSessionFactory 创建一个SqlSession
SqlSession 调用一个 quary(查询)Executor执行器,是为了执行sql语句
作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能
创建一个新的StatementHandler (参数执行器)
MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护
(1、根据传递的参数,完成SQL语句的动态解析,生成BoundSql对象,供StatementHandler使用;
(2、为查询创建缓存,以提高性能(具体它的缓存机制不是本文的重点,我会单独拿出来跟大家探讨,感兴趣的读者可以关注我的其他博文);
(3、创建JDBC的Statement连接对象,传递给StatementHandler对象,返回List查询结果。
功能
封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合
负责将JDBC返回的ResultSet结果集对象转换成List类型的集合
主要部件
负责对用户传递的参数转换成JDBC Statement 所需要的参数,
负责java数据类型和jdbc数据类型之间的映射和转换
preparedstatement
simplestatement
callablestatement
statement
resultset
jdbc
MappedStatement维护了一条<select|update|delete|insert>节点的封装,
负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回
包含
表示动态生成的SQL语句以及相应的参数信息
BoundSql
MapperProxyFactory
代理对象,用于代理Mapper接口方法
MapperProxy
其他部件
定位资源位置,加载资源,将xml加载成流
build 加载配置文件
new XMLConfigBuilder 配置文件解析器
build(config) 建立解析完的 Configuration
调用new DefaultSqlSessionFactory
XMLMapperBuilder
XMLStatementBuilder
是抽象类BaseBuilder 的一个子类,专门用来解析全局配置文件,针对不同的构建目标还有其他的一些子类
解析-config 配置文件、Mapper 文件、Mapper 接口上的注解的解析
作用
调用 new Configuration
Parse()解析全集配置文件及映射器文件,填充Configuration 及MpppedStatement
是对Mapper 映射器的解析
parse()
方法
XMLConfigBuilder
MyBatis 全局配置文件的顺序不可以颠倒
最后,MapperRegistry 也会放到Configuration 里面去。
注意
把 Configuration 返回给 XMLConfigBuilder
Configuration
返回给SqlSessionFactoryBuilder一个 DefaultSqlSessionFactory
DefaultSqlSessionFactory
组件
第一步配置解析过程:
取到opensqlsession
getDefaultExecutorType() 获取执行器类型
openSessionFromDataSource
返回执行器类型
获取 Enviroment
创建事务TX
SINPLE/REUSE/BATCH
1.创建Executor基本类型
CachingExecutor((Executot)executor)
2.二级缓存包装
3.拦截器包装
DefaultSqlSession
第二步会话创建过程:
getMapper(Claaa<T> type)
getMapper(Claaa<T> type)
根据接口类型获取工厂类(MapperProxyFactory this .knownMappers.get(type)
MapperRegistry
newInstance()创建MapperProxy实例
Proxy.newProxyInstance 创建接口代理对象
MapperProxyFactory
返回MapperProxy实例
MapperProxy
DefaultSqlSession 的getMapper()方法,调用了Configuration 的getMapper()方法。继而调到 MapperRegistry.getMapper:
Mapper 对象是怎么获得的?
不需要实现类的原因:我们只需要根据接口类型+方法的名称,就可以找到Statement ID 了,而唯一要做的一件事情也是这件,所以不需要实现类.在MapperProxy里面直接执行逻辑(也就是执行SQL)就可以
JDK 动态代理和MyBatis 用到的JDK 动态代理有什么区别
疑问
获得Mapper 对象的过程,实质上是获取了一个MapperProxy 的代理对象
第三步获得Mapper 对象:
invoke()
执行execute(this.sqlSession,args)
MapperMethod
1.selectone
2.selectList
3.获取MappedStlatement执行query()
1.获取BoundSq1
2.创建CacheKey
3.获取本地缓存queryFromDatabase插入本地缓存
BaseExecutor
1.获取Configuration
2.创建StatementHandler\\parameterHandler\\ResultSetHandler
3.创建Connection
4.parameterize处理参数Handler.query(stmt,resultHandler)
simpleExecutor
1.语句编译
2.ps.execute()执行sqlhandleResultSets
RoutingstatementHandler
处理结果集
DefaultResultSetHandler
第四步执行sql:
详细步骤流程
mybatis流程具象化知识学习笔记
0 条评论
回复 删除
下一页