mybatis流程具象化
SqlSessionFactoryBuilder
工厂建造工人
创建工厂
Configuration
小箱子
放置说明书,记录操作过程
sqlSessionFactory
管子生产工厂
生产管子
StatementHandler
水流形状转化器(入口)
转化水流形状,宽窄,三角形,最窄的时候,相当于关闭,所以可以控制水流大小
ResultSetHandler
出口形状转换
黑心的水资源提供者,中间商减小水流,垄断,高价买水
水流管子工厂放水事件
管子水流工厂简版
水流形状转化器(入口)
管子
出口形状转换
黑心的水资源提供者,中间商减小水流,垄断,高价买水
简述: 工厂建造者建造了一个工厂,通过一个小册子,工厂将建立池子的说明书(后续可以持续更新)的放入小箱子,工厂建立了一个连接产品通道(管子)的池子, 池子创建了一个通道(sqlsession) ,池子使用了query,开关按钮(excutor)打开,水流就通过了(一段sql),可以修改删除水流.开关,有一个指针,可以设置放水流的大小.开关是智能开关,还有记录水流量的功能,为了防止开关出现问题,加快水流调度的速度,防止误触,最终还有一个保险按钮(如同手枪的保险)ResultSetHandler.
简介
MyBatis框架主要完成的是以下2件事情:
根据JDBC规范建立与数据库的连接。
通过反射打通Java对象与数据库参数交互之间相互转换的关系。
比喻
餐厅的服务流程
第一个是跟客户打交道的服务员,它是用来接收程序的工作指令的,我们把它叫做接口层。
第二个是后台的厨师,他们根据客户的点菜单,把原材料加工成成品,然后传到窗口。这一层是真正去操作数据的,我们把它叫做核心层。
最后就是餐厅也需要有人做后勤(比如清洁、采购、财务),来支持厨师的工作和整个餐厅的运营。我们把它叫做基础层。
动态代理
太监
接口Class对象是大内太监,里面的方法和字段比做他的一身武艺,但是他没有小DD(构造器),
所以不能new实例。一身武艺后继无人。
那怎么办呢?
正常途径(implements)
写一个类,实现该接口。这个就相当于大街上拉了一个人,认他做干爹。一身武艺传给他,只是比他干爹多了小DD,可以new实例。
非正常途径(动态代理):
通过妙手圣医Proxy的克隆大法(Proxy.getProxyClass())克隆一个Class,但是有小DD。所以这个克隆人Class可以创建实例,也就是代理对象。
代理Class其实就是附有构造器的接口Class,一样的类结构信息,却能创建实例。
简述
阶段
初始化阶段:读取XML配置文件和注解中的配置信息,创建解析对象,并完成各个模块的初始化工作。就是把我们的配置文件加载到内存里面去。在sqlSession初始化的时候加载到内存中去的。
代理阶段:封装iBatis的编程模型,使用mapper接口开发的初始化工作;
数据读写阶段:通过SqlSession完成SQL的解析,参数的映射,SQL的执行,结果的反射解析过程。
MyBatis的设计思路
创建SqlSessionFactory实例
实例化过程中,加载配置文件创建configuration对象
通过factory创建SqlSession
通过SqlSession获取mapper接口动态代理
动态代理回调sqlsession中某查询方法
SqlSession将查询方法转发给Executor
Executor基于JDBC访问数据库获取数据
Executor通过反射将数据转换成POJO并返回;给SqlSession
将数据返回给调用者
分层
接口层
首先接口层是我们打交道最多的。核心对象是SqlSession,它是上层应用和MyBatis打交道的桥梁,SqlSession 上定义了非常多的对数据库的操作方法。接口层在接收到调用请求的时候,会调用核心处理层的相应模块来完成具体的数据库操作。
两种方式
a.使用传统的MyBatis提供的API;
这是传统的传递Statement Id 和查询参数给 SqlSession 对象,使用 SqlSession对象完成和数据库的交互;MyBatis 提供了非常方便和简单的API,供用户实现对数据库的增删改查数据操作,以及对数据库连接信息和MyBatis 自身配置信息的维护操作
上述使用MyBatis 的方法,是创建一个和数据库打交道的SqlSession对象,然后根据Statement Id 和参数来操作数据库,这种方式固然很简单和实用,但是它不符合面向对象语言的概念和面向接口编程的编程习惯。由于面向接口的编程是面向对象的大趋势,MyBatis 为了适应这一趋势,增加了第二种使用MyBatis 支持接口(Interface)调用方式。
b. 使用Mapper接口
MyBatis 将配置文件中的每一个 节点抽象为一个 Mapper 接口,而这个接口中声明的方法和跟 节点中的 节点项对应,即 节点的id值为Mapper 接口中的方法名称,parameterType 值表示Mapper 对应方法的入参类型,而resultMap 值则对应了Mapper 接口表示的返回值类型或者返回结果集的元素类型。
据MyBatis 的配置规范配置好后,通过SqlSession.getMapper(XXXMapper.class) 方法,MyBatis 会根据相应的接口声明的方法信息,通过动态代理机制生成一个Mapper 实例,我们使用Mapper 接口的某一个方法时,MyBatis 会根据这个方法的方法名和参数类型,确定Statement Id,底层还是通过SqlSession.select("statementId",parameterObject);或者SqlSession.update("statementId",parameterObject); 等等来实现对数据库的操作,(至于这里的动态机制是怎样实现的,我将准备专门一片文章来讨论,敬请关注~)
MyBatis 引用Mapper 接口这种调用方式,纯粹是为了满足面向接口编程的需要。(其实还有一个原因是在于,面向接口的编程,使得用户在接口上可以使用注解来配置SQL语句,这样就可以脱离XML配置文件,实现“0配置”
核心处理层
内容
接下来是核心处理层。既然叫核心处理层,也就是跟数据库操作相关的动作都是在这一层完成的。核心处理层主要做了这几件事
插件也属于核心层,这是由它的工作方式和拦截的对象决定的。
主要功能
a. 通过传入参数构建动态SQL语句;
b. SQL语句的执行以及封装查询结果集成List
步骤
把接口中传入的参数解析并且映射成JDBC 类型;
解析xml 文件中的SQL 语句,包括插入参数,和动态SQL 的生成;
执行SQL 语句;
处理结果集,并映射成Java 对象。
基础支持层
内容
最后一个就是基础支持层。基础支持层主要是一些抽取出来的通用的功能(实现复用),用来支持核心处理层的功能。比如数据源、缓存(请点击跳转至缓存详解)、日志、xml 解析、反射、IO、事务等等这些功能。
3大机制和sql配置
3.1. 事务管理机制
3.2. 连接池管理机制
3.3. 缓存机制
3. 4. SQL语句的配置方式
传统的MyBatis 配置SQL 语句方式就是使用XML文件进行配置的,但是这种方式不能很好地支持面向接口编程的理念,为了支持面向接口的编程,MyBatis 引入了Mapper接口的概念,面向接口的引入,对使用注解来配置SQL 语句成为可能,用户只需要在接口上添加必要的注解即可,不用再去配置XML文件了,但是,目前的MyBatis 只是对注解配置SQL 语句提供了有限的支持,某些高级功能还是要依赖XML配置文件配置SQL 语句。
步骤
通过建造者模式创建一个工厂类,定位,加载,解析配置文件的就是在这一步完成的,包括mybatis-config.xml 和Mapper 适配器文件。
通过SqlSessionFactory 创建一个SqlSession。
获得Mapper 对象。
调用接口方法(insert,delete,update,select)。
主要部件
SqlSessionFactoryBuilder
通过SqlSessionFactoryBuilder 解析mybatis-config.xml 文件中的 Configuration 创建一个 sqlSessionFactory
Configuration
MyBatis所有的配置信息都维持在Configuration对象之中。
sqlSessionFactory
通过sqlSessionFactory 创建一个SqlSession
SqlSession
SqlSession 调用一个 quary(查询)Executor执行器,是为了执行sql语句
作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能
SqlSession根据Statement ID, 在mybatis配置对象Configuration中获取到对应的MappedStatement对象,然后调用mybatis执行器来执行具体的操作。
Executor
创建一个新的StatementHandler (参数执行器)
MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护
功能
(1、根据传递的参数,完成SQL语句的动态解析,生成BoundSql对象,供StatementHandler使用;
(2、为查询创建缓存,以提高性能(具体它的缓存机制不是本文的重点,我会单独拿出来跟大家探讨,感兴趣的读者可以关注我的其他博文);
(3、创建JDBC的Statement连接对象,传递给StatementHandler对象,返回List查询结果。
StatementHandler
调用ResultSetHandler (结果器返回结果),执行SQl语句,不同的SQl语句返回不同的结果
封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合
ResultSetHandler
负责将JDBC返回的ResultSet结果集对象转换成List类型的集合
其他部件
ParameterHandler
负责对用户传递的参数转换成JDBC Statement 所需要的参数,
TypeHandler
负责java数据类型和jdbc数据类型之间的映射和转换
jdbc
statement
preparedstatement
simplestatement
callablestatement
resultset
MappedStatement
MappedStatement维护了一条<select|update|delete|insert>节点的封装,
包含
SqlSource
负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回
resultmap
BoundSql
表示动态生成的SQL语句以及相应的参数信息
MapperProxy
MapperProxyFactory
代理对象,用于代理Mapper接口方法