mybatis简介
mybatis是一款优秀的半自动化持久层框架,它支持定制化SQL,存储过程以及高级映射。Mybatis避免了几乎所有的JDBC代码和手动设置参数获取结果集。Mybatis可以使用简单的XML或者注解来配置和映射原生信息,将java的pojo映射成数据库中的记录。
优点:SQL统一维护配置文件中,方便管理维护,半自动化,插件支持,简单易学
github地址:https://github.com/mybatis/mybatis-3
基础架构简介
基础架构层大体一共可以分为三层,分别是基础支撑层,数据处理层,接口层。
基础支撑层:
负责最基本的基础功能支撑,包括连接管理,失误管理,配置加载,缓存处理。这些都是共用的东西,将他们抽取出来最为最基础的组件,为上层数据处理层提供最基础的支撑。
数据处理层
负责具体的SQL查找,SQL解析,SQL执行,和执行结果的映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
API接口层
提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库,接口层一接收到请求就会调用数据处理层来完成具体的数据处理。
执行流程简介
具体可以分为以下几步:
1、加载配置文件到Configuration
2、构建SQlSessionFactory
3、打开SqlSession会话
4、Executor开始处理请求
5、SqlSource解析Sql
6、StatementHandler执行sql
7、parameterHandler设置参数
8、StatementHandler执行Sql
9、ResultSetHandler处理结果集
Executor:是跟SqlSession绑定在一起的,每一个SqlSession都拥有一个新的Executor对象,由Configuration创建
SIMPLE(默认), 每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象
REUSE, 以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map
BATCH,执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理的;BatchExecutor相当于维护了多个桶,每个桶里都装了很多属于自己的SQL,就像苹果蓝里装了很多苹果,番茄蓝里装了很多番茄,最后,再统一倒进仓库
cacheEnabled 如果为true,会创建CachingExecutor,先从缓存中获取查询结果,存在就返回,不存在,再委托给Executor delegate去数据库取,delegate可以是上面任一的SimpleExecutor、ReuseExecutor、BatchExecutor
Statement:
STATEMENT,不预编译
PREPARED(默认),预编译
CALLABLE,存储过程
参数解析
参数解析是将请求参数列表用名字一一标明,结果存放于map中,key为名称,value为参数值,以便后续参数映射:
(1)给每个参数指定名称,维护到一个names map中,key为参数位置,从0开始,value为@param注解的参数名称,特殊的,如果没有被注解的则给定默认名字
(2)维护参数名称到参数值的映射,根据names中的参数名称为key,值为value维护到parameterObject map中,无@param且参数只有一个,则不作处理。
(3)如果参数没有做map化处理,且是集合或者数组的,将为其指定特殊key维护到map中。
----指定入参名称--------------------------------------------------------------------------------------------------
由ParamNameResolver在首次mapper实例方法被其他请求调用时指定,并缓存于MapperProxy中,具体步骤如下:
a.获取方法上所有参数名称
b.获取参数上的注解集合
c.遍历注解
d.特殊参数跳过
e.取出@Param注解中的name
f.无注解情况给定默认name
g.key - value,value-name存入map
---------参数名称与值映射------------------------------------------------------------------------------
根据names中的参数名称为key,值为value维护到parameterObject map中,无@Param且参数只有一个,则不做处理:
a、没有使用@Param注解的情况,且只有一个入参,则直接返回入参值
b、遍历names map
c、将names map里面的value,即参数名称作为key, 入参相对于位置上值作为value存入map
d、额外的增加param+位置(从1开始)为key,入参相对于位置上值作为value存入map
--------包装集合与Array参数-----------------------------------------------------------------------------------
parameterObject 如果是集合或者是数组的,将为其指定特殊key维护到map中
前面包装的基础上再次包装: 集合实现被包装为map collection->入参值
集合下List实现则会增加list封装 list->入参值
数组被包装为map array>入参值
SQL解析
SQL解析是将定义在mapper.xml或者直接在mapper接口方法上的定义的sql块(含有sql、${} 等标签)解析为可执行或者可预编译的sql过程。
1、在配置文件加载时,根据sql类型加载为不同SqlSource,以及SqlSource下SqlNode节点
2、执行sql时向SqlSource获取sql,SqlSource解析sql动态部分
1、可预编译理解:sql(包含指令部分+参数部分)的指令部分先编译,后续给定参数。
2、指令:在哪张表哪个条数据哪个字段上干什么事情