MyBatis架构

MyBatis依赖的jar不多,而且代码行数也没多少,其中使用了大量的设计模式,值得好好学习。下图是MyBatis的一张架构图,来自Java框架篇—Mybatis 入门

Mybatis的功能架构分为三层:

  • API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
  • 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
  • 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

MyBatis整个项目的包结构如下:

.
└── org
    └── apache
        └── ibatis
            ├── annotations
            ├── binding
            ├── builder
            ├── cache
            ├── cursor
            ├── datasource
            ├── exceptions
            ├── executor
            ├── io
            ├── jdbc
            ├── logging
            ├── mapping
            ├── parsing
            ├── plugin
            ├── reflection
            ├── scripting
            ├── session
            ├── transaction
            └── type

1.兵马未动,日志先行

org.apache.ibatis.logging

org.apache.ibatis.logging.commons

org.apache.ibatis.logging.jdbc

org.apache.ibatis.logging.jdk14

org.apache.ibatis.logging.log4j

org.apache.ibatis.logging.log4j2

org.apache.ibatis.logging.nologging

org.apache.ibatis.logging.slf4j

org.apache.ibatis.logging.stdout

2.异常

org.apache.ibatis.exceptions

3.缓存

org.apache.ibatis.cache

org.apache.ibatis.cache.decorators

org.apache.ibatis.cache.impl

4.解析

org.apache.ibatis.parsing

xml解析,${} 格式的字符串解析

源码分析可以参考http://www.cnblogs.com/sunzhenchao/p/3161093.html

5.类型处理器

org.apache.ibatis.type

实现java和jdbc中的类型之间转换

源码分析可以参考http://www.cnblogs.com/sunzhenchao/archive/2013/04/09/3009431.html

6.IO

org.apache.ibatis.io

通过类加载器在jar包中寻找一个package下满足条件(比如某个接口的子类)的所有类

7.反射

org.apache.ibatis.reflection

org.apache.ibatis.reflection.factory

org.apache.ibatis.reflection.invoker

org.apache.ibatis.reflection.property

org.apache.ibatis.reflection.wrapper

可以参考MetaObjectTest来跟踪调试,基本上用到了reflection包下所有的类

8.数据源

org.apache.ibatis.datasource

org.apache.ibatis.datasource.jndi

org.apache.ibatis.datasource.pooled

org.apache.ibatis.datasource.unpooled

9.事务

org.apache.ibatis.transaction

org.apache.ibatis.transaction.jdbc

org.apache.ibatis.transaction.managed

10.会话

org.apache.ibatis.session

org.apache.ibatis.session.defaults

11.jdbc单元测试工具

org.apache.ibatis.jdbc

12.构建

org.apache.ibatis.builder

org.apache.ibatis.builder.annotation

org.apache.ibatis.builder.xml

13.映射

org.apache.ibatis.mapping

14.脚本

org.apache.ibatis.scripting

org.apache.ibatis.scripting.defaults

org.apache.ibatis.scripting.xmltags

15.注解

org.apache.ibatis.annotations

16.绑定

org.apache.ibatis.binding

17.执行器

org.apache.ibatis.executor

org.apache.ibatis.executor.keygen

org.apache.ibatis.executor.loader

org.apache.ibatis.executor.loader.cglib

org.apache.ibatis.executor.loader.javassist

org.apache.ibatis.executor.parameter

org.apache.ibatis.executor.result

org.apache.ibatis.executor.resultset

org.apache.ibatis.executor.statement

18.插件

org.apache.ibatis.plugin


注释①

mybatis通过SqlSessionFactoryBuilder作为入口,通过传入配置文件,使用了BaseBuilder实现类进行配置文件解析,具体实现类是XMLConfigBuilder,在这里mybatis对配置的项进行了全面解析,只不过不是所有的解析都放在了XMLConfigBuilder,XMLConfigBuilder解析了二级节点,并作为一个总入口,还有另外几个类继承了BaseBuilder,用于解析不同的配置。而解析到的配置项信息,基本都保存在了Configuration这个类,可以看到多处地方依赖到它。

之后通过配置获取到SqlSessionFactory,可以看到SqlSessionFactoryBuilder提供了一个build方法,就是返回SqlSessionFactory的。

注释②

而SqlSessionFactory只是一个接口,默认实现有DeaultSqlSessionFactory。通过SqlSessionFactory.openSession的几个多态方法,可以获取到SqlSession。

注释③

而SqlSession也只是一个接口,怎么理解SqlSession呢,其实Session即是一次会话,假如我们把某次请求与数据库连接Connection的交互,看成是一次会话,那就可以理解SqlSession了。SqlSession是请求与数据库的一次交互,交互完成之后,Session则结束,但Session结束不代表数据库连接也关闭,只是这次会话终止了,但是数据库连接依旧是返回给连接池。

这里的SqlSession即是对一次交互信息的封装,请求可以通过SqlSession的方法(如图:CRUD )进行操作,而数据库连接,依旧由SqlSessionFactory注入。

注释②

如图我们可以看到SqlSessionFactory获取到TransactionFactory,一个事务的工厂类接口,而通过这个工厂具体实现类可以产生多个事务Transaction(具体参考ManagedTransactionFactory),Transaction抽象了一个方法getConnection,通过这个方法我们可以获取到不同事务级别的connection。mybatis的代码是这样的:

ManagedTransaction.java

protected void openConnection() throws SQLException {
if (log.isDebugEnabled()) {
log.debug(“Opening JDBC Connection”);
}
this.connection = this.dataSource.getConnection();
if (this.level != null) {
this.connection.setTransactionIsolation(this.level.getLevel());
}
}

注释④

这个时候可能大家觉得万事俱备了,SqlSession都定义好了CRUD 方法了,那它也会帮忙将语句扔给Connection操作,其实不然。这里mybatis还抽象了接口Execute。

Execute才是真正将sql与Connection打交道的地方。

图中我们可以看到Execute有四个实现类,通过名称我们不难发现它们各自的用途,例如CachingExecutor.java,mybatis默认是有缓存的,就是通过这个类实现的。

还有一个点,每个Execute实现类中,都可以发现有这样一个定义和构造方法

private Executor delegate;

public CachingExecutor(Executor delegate) {
this.delegate = delegate;
delegate.setExecutorWrapper(this);
}

所以这里我们也可以看到,其实Executor有个链结构,一步一步往下执行,所以在真正执行查询时,外面是嵌套了一层CachingExecutor,证据在这里。

  1. public Executor newExecutor(Transaction transaction, ExecutorType executorType, boolean autoCommit) {
  2. executorType = executorType == null ? defaultExecutorType : executorType;
  3. executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
  4. Executor executor;
  5. if (ExecutorType.BATCH == executorType) {
  6. executor = new BatchExecutor(this, transaction);
  7. } else if (ExecutorType.REUSE == executorType) {
  8. executor = new ReuseExecutor(this, transaction);
  9. } else {
  10. executor = new SimpleExecutor(this, transaction);
  11. }
  12. if (cacheEnabled) {
  13. executor = new CachingExecutor(executor, autoCommit);
  14. }
  15. executor = (Executor) interceptorChain.pluginAll(executor);
  16. return executor;
  17. }

在Execute中,还有更深层的执行逻辑,这个后面文章继续分析。

转载请注明出处:http://sukerz.scse.cn/index.php/2016/02/01/mybatis-framework/

MyBatis架构图的更多相关文章

  1. Atitit jOrgChart的使用  组织架构图css html

    Atitit jOrgChart的使用  组织架构图css html 1. 项目要做组织架构图,要把它做成自上而下的树形结构,于是决定1 2. Html导入 以来的css js1 2.1. 数据来源 ...

  2. 飞达资讯App总体介绍及关系架构图

    飞达资讯App总体介绍: 下图为飞达资讯App的关系架构图: 该App关系架构图所需的图片云盘链接地址:http://pan.baidu.com/s/1gfHIe4b 提取密码:x1nr 该App的云 ...

  3. 关于SAP4.7的几个架构图

    http://blog.itpub.net/92530/viewspace-154881/ 1.SAP基本架构图 2.SAP的应用层的工作进程架构图 3.SAP的内存类型图 4.SAP数据访问架构图 ...

  4. android系统架构图

    android的系统架构和其操作系统一样,采用了分层的架构.从架构图看,android分为四个层,从高层到低层分别是应用程序层.应用程序框架层.系统运行库层和Linux核心层. 1.应用程序 Andr ...

  5. struts2原理架构图

    struts2 原理架构图

  6. iphone开发 IOS 组织架构图

    转载自 :http://blog.csdn.net/mashi321323/article/details/18267719   登录|注册     mashi321323的专栏       目录视图 ...

  7. LoadRunner相关架构图

    LoadRunner概览图: Lr架构图:

  8. live555源码学习1---Socket流程架构图

    怎么说呢,换了工作环境,好多软件公司禁止使用了,有道笔记也无法使用了.发现博客园还可以上传图片,以后只能在这里记录了. 越发的感觉需要尽快把live555的代码拿下.因为工作环境问题,webrtc的源 ...

  9. Kubernetes 架构图

    Kubernetes 架构图: Pod K8S中最基础的调度单位是Pod,它有网络,有存储.Pod里面运行着一个或者若干个docker容器.同一个Pod里的容器共享同一个网络命名空间,可以使用loca ...

随机推荐

  1. iOS目录结构

    默认情况下,每个沙盒含有3个文件夹:Documents, Library 和 tmp.因为应用的沙盒机制,应用只能在几个目录下读写文件 Documents:苹果建议将程序中建立的或在程序中浏览到的文件 ...

  2. PHP中定义常量的几种方式与区别

    [问]在php中定义常量时,const与define的区别? [答]使用const使得代码简单易读,const本身就是一个语言结构,而define是一个函数.另外const在编译时要比define快很 ...

  3. 防止iframe嵌套

    如果你哪个页面不想被嵌套 下面js代码可以解决(我的是火狐) 慎用 <script type="text/javascript">          window.on ...

  4. java中的异常结构

    1.基类为Throwable. 2.Error和Exception分别继承Throwable. 3.Error类异常描述了Java运行系统中的内部错误以及资源耗尽的情形.应用程序不应该抛出这种类型的对 ...

  5. 数组去重的三种方法及from方法

    直接上代码: var str="adbbckddwerivka"; var arr=str.split(""); console.log(arr); //ind ...

  6. Bootstrap_Javascript_图片轮播

    一 . 结构分析 一个轮播图片主要包括三个部分: ☑ 轮播的图片 ☑ 轮播图片的计数器 ☑ 轮播图片的控制器 第一步:设计轮播图片的容器.在 Bootstrap 框架中采用 carousel 样式,并 ...

  7. php设计模式之迭代器模式

    今天的PHP设计模式系列的主角是迭代器(Iterator)模式,迭代器模式提供了抽象:位于对象图不明部分的一组对象(或标量)集合上的迭代. 迭代器(Iterator)模式,它在一个很常见的过程上提供了 ...

  8. Python 环境

    文章出处:http://www.cnblogs.com/winstic/,请保留此连接 总结一下自己使用python过程中安装三方包的方法 Python 安装 Python的安装非常简单,本人使用的w ...

  9. IIC 概述之1

    概述: I²C 是Inter-Integrated Circuit的缩写,发音为"eye-squared cee" or "eye-two-cee" , 它是一 ...

  10. Josephus

    利用循环链表模拟约瑟夫问题,把自杀的人的顺序排列出来 代码如下: #include<stdio.h> #include<stdlib.h> typedef int status ...