目录

一、为什么要用MyBatis

1、Mybatis简介

2、持久化框架对比

二、Mybatis架构原理

1、架构设计

2、主要构件及其相互关系

1)Mybatis主要构件描述

2)Mybatis主要构件结构

三、Mybatis缓存原理

1、Mybatis缓存简介

2、一级缓存

1)简介

2)缓存生命周期流程图

2、二级缓存

3、缓存问题

1)一级缓存

2)二级缓存

四、Mybatis中设计模式应用

1、Builder构建者模式

1)背景

2)Mybatis中的应用

2、工厂模式

1)背景

2)Mybatis中的应用

3、代理模式

1)背景

五、阅读框架的反思

六、参考资料


一、为什么要用MyBatis

1、Mybatis简介

MyBatis是一款优秀的基于ORM的半自动轻量级持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生类型、接口和Java的POJO (Plain Old Java Objects,普通老式Java对象) 为数据库中的记录 。

2、持久化框架对比

方式

优点

缺点

场景

Hibernate

不再需要编写SQL就可以通过映射关系来操作数据库;提升开发效率

当多表关联超过3个时Hibermate的级联会损失很多性能;灵活性太差

适合性能要求不太苛刻的系统,不适合需要大量复杂查询的系统

SpringJDBC

内嵌Spring框架中、支持AOP;提供了统一的异常处理,框架处理了异常;事务管理

只是对原生JDBC进行一层非常薄的封装,没有缓存

需要在代码中嵌入SQL语句,适用中小型项目

Mybatis

灵活性更好,满足定制SQL和性能优化的需求

编写SQL和映射规则,工作量相对大

性能要求高、响应快、灵活的系统;sql修改、优化比较方便

二、Mybatis架构原理

1、架构设计

我们把Mybatis的功能架构分为三层:

(1) API接口层:提供给外部使用的接口 API,开发人员通过这些本地API来操纵数据库。接口层一接收到

调用请求就会调用数据处理层来完成具体的数据处理。 MyBatis和数据库的交互有两种方式:

a. 使用传统的MyBatis提供的API ;

b. 使用Mapper代理的方式

(2) 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

(3) 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是 共 用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑

2、主要构件及其相互关系

1)Mybatis主要构件描述

构件

描述

SqlSession

作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能

Executor

MyBatis执行器,是MyBatis调度的核心,负责SQL语句的生成和查询缓存的维护

StatementHandler

封装了JDBC Statement操作,负责对JDBC statement的操作,如设置参数、将Statement结果集转换成List集合。

ParameterHandler

负责对用户传递的参数转换成JDBC Statement所需要的参数

ResultSetHandler

负责将JDBC返回的ResultSet结果集对象转换成List类型的集合;

TypeHandler

负责java数据类型和jdbc数据类型之间的映射和转换

MappedStatement

MappedStatement维护了一条<select | update | delete | insert>节点的封装

ResultMap

保存<select | update | delete | insert>中配置的结果集类型

SqlSource

负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封 装到BoundSql对象中,并返回

BoundSql

表示动态生成的SQL语句以及相应的参数信息

2)Mybatis主要构件结构

三、Mybatis缓存原理

1、Mybatis缓存简介

缓存就是内存中的数据,常常来自对数据库查询结果的保存,使用缓存,我们可以避免频繁的与数据库进行交互,进而提高响应速度。

mybatis也提供了对缓存的支持,分为一级缓存与二级缓存,可以通过下图来理解

2)二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

2、一级缓存

1)简介

一级缓存是SqlSession级别的缓存,默认开启。在操作数据库时需要构造SqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据结构。不同的SqlSession之间的缓存数据区域(HashMap)是互不影响的。

2)缓存生命周期流程图

2、二级缓存

二级缓存的原理和一级缓存原理一样,第一次查询,会将数据放入缓存中,然后第二次查询则会直接去缓存中取。但是一级缓存是基于sqlSession的,而二级缓存是基于mapper文件的namespace的,也就是说多个sqlSession可以共享一个mapper中的二级缓存区域,并且如果两个mapper的namespace相同,即使是两个mapper,那么这两个mapper中执行sql查询到的数据也将存在相同的二级缓存区域中

需要注意:二级缓存存的不是对象而是数据,一级缓存存的是对象(同一个地址)而不是数据

一级缓存从BaseExecutor开始分析,而二级缓存需要从CachingExecutor分析,生命周期流程图和一级缓存基本一致。

3、缓存问题

通过上面对于缓存的介绍,我们发现Mybatis缓存都是本地缓存,在分布式的情况下会出现缓存一致性问题。例如一级缓存都是默认开启的为什么没有出现这类问题呢?

1)一级缓存

前面所提到的,一级缓存是SqlSession级别的缓存,默认开启。

SqlSessioin是什么?

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的范围是请求或方法范围。绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。也绝不能将 SqlSession 实例的引用放在任何类型的管理范围中,比如 Serlvet 架构中的 HttpSession。如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的范围中。换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。

所以结论:如果多个请求同一个事务中,那么多个请求都在共用一个SqlSession,反之每个请求都会创建一个SqlSession。

2)二级缓存

二级缓存是基于mapper文件的namespace的缓存,所以在分布式的情况下会很可能会缓存一致性问题。所以官方给的方案是手动开始。

四、Mybatis中设计模式应用

1、Builder构建者模式

1)背景

Builder模式的定义是"将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表 示。”,它属于创建类模式,一般来说,如果一个对象的构建比较复杂,超出了构造函数所能包含的范 围,就可以使用工厂模式和Builder模式,相对于工厂模式会产出一个完整的产品,Builder应用于更加 复杂的对象的构建,甚至只会构建产品的一个部分,直白来说,就是使用多个简单的对象一步一步构建 成一个复杂的对象。

2)Mybatis中的应用

SqlSessionFactory 的构建过程:

Mybatis的初始化工作非常复杂,不是只用一个构造函数就能搞定的。所以使用了建造者模式,使用了大量的Builder,进行分层构造,核心对象Configuration使用了XmlConfigBuilder来进行构造

在Mybatis环境的初始化过程中,SqlSessionFactoryBuilder会调用XMLConfigBuilder读取所有的 MybatisMapConfig.xml 和所有的 *Mapper.xml 文件,构建 Mybatis 运行的核心对象 Configuration 对 象,然后将该Configuration对象作为参数构建一个SqlSessionFactory对象。

其中 XMLConfigBuilder 在构建 Configuration 对象时,也会调用 XMLMapperBuilder 用于读取 *Mapper 文件,而XMLMapperBuilder会使用XMLStatementBuilder来读取和build所有的SQL语句。

在这个过程中,有一个相似的特点,就是这些Builder会读取文件或者配置,然后做大量的XpathParser 解析、配置或语法的解析、反射生成对象、存入结果缓存等步骤,这么多的工作都不是一个构造函数所 能包括的,因此大量采用了 Builder模式来解决

SqlSessionFactoryBuilder类根据不同的输入参数来构建SqlSessionFactory这个工厂对象

2、工厂模式

1)背景

在Mybatis中比如SqlSessionFactory使用的是工厂模式,该工厂没有那么复杂的逻辑,是一个简单工厂模式。

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于创建型模式。

在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

2)Mybatis中的应用

Mybatis中执行Sql语句、获取Mappers、管理事务的核心接口SqlSession的创建过程使用到了工厂模式。

如SqlSessionFactory用来负责SqlSession的创建

可以看到,该Factory的openSession ()方法重载了很多个,来构建核心的SqlSession对象。 在DefaultSqlSessionFactory的默认工厂实现里,有一个方法可以看出工厂怎么产出一个产品:

这是一个openSession调用的底层方法,该方法先从configuration读取对应的环境配置,然后初始化 TransactionFactory 获得一个 Transaction 对象,然后通过 Transaction 获取一个 Executor 对象,最后通过configuration、Executor、autoCommit三个参数构建了 SqlSession。

3、代理模式

1)背景

代理模式(Proxy Pattern):给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做Proxy,它是一种对象结构型模式。

2)Mybatis中的应用

代理模式可以认为是Mybatis的核心使用模式,正是由于这个模式,我们只需要编写Mapper.java接口,不需要实现,由Mybatis后台帮我们完成具体SQL的执行。 当我们使用Configuration的getMapper方法时,会调用mapperRegistry.getMapper方法,而该方法又会调用 mapperProxyFactory.newInstance(sqlSession)来生成一个具体的代理:

在这里,先通过T newInstance(SqlSession sqlSession)方法会得到一个MapperProxy对象,然后调用T newInstance(MapperProxy mapperProxy)生成代理对象然后返回。而查看MapperProxy的代码,可以看到如下内容:

非常典型的,该MapperProxy类实现了InvocationHandler接口,并且实现了该接口的invoke方法。通过这种方式,我们只需要编写Mapper.java接口类,当真正执行一个Mapper接口的时候,就会转发给 MapperProxy.invoke方法,而该方法则会调用后续的 sqlSession.cud>executor.execute>prepareStatement 等一系列方法,完成 SQL 的执行和返回

五、阅读框架的反思

知其然也要知其所以然,一门技术只是会用那只是入门,只有熟练了,了解了其中原理才有用。用了一门技术遇到问题后,如何去快速解决,解决的思路是什么,一般解决问题的能力能直接体现你的综合能力。因为有的棘手问题不是短时间能解决或者说不是能顺利解决的,你需要利用你的技术广度和深度再加上你以往解决问题的经验。

我们虽成为不了北乔峰,但可以学习南慕容,最后要成为杨过。

自己要会造轮子先要学会别人怎么造轮子,天龙八部中南北两大高手,北乔峰是天资很好靠名师指点最后成为江湖顶级高手,南慕容是靠学习各大帮派的武功也成为了高手,射雕英雄传中杨过从蛤蟆功开始学起,中间经过神雕指点成为江湖高手,最后自己悟出黯然销魂掌终成一代大侠。

向乔峰一样天资聪明,武功根基良好的人并不多,大部分都是资质一般,要靠后天勤学苦练,在学习中不断悟道,总有一天也能有成。

学习源码也是一样,看一遍看不懂很正常,看一遍有一遍的理解,看不懂就在看一遍,直到看懂为止,看的过程要多思考,子曰:“学而不思则罔,思而不学则殆”,这个地方为什么要这样设计,如果是你应该怎么设计,怎么才是更好的设计,学习别人的设计思想,你可以实现一个优秀的框架。在阅读优秀框架源码的过程,我们吸收其中的设计模式和架构模式,对比平日里自己的设计方式,站在巨人的肩膀上思考,一步步提升境界。

术生道,道生术,术中有道,道中有术,道术相连才能生生不息

这里的术指的是架构设计模式,道指的是架构思想,两者是相辅相成的,通过学习前人的经验,行成思考、对比,然后去实践你的架构设计,不断的在实践中理解、思考架构设计思想,在将得到的架构思想再去实践,你用架构师的思想去思考问题解决问题你就是架构师,没有更好的架构,只有合适的架构,好的代码不是写出来的,如同娃娃学步一样,先学先看,然后在改再改,一步步尝试走出来的,架构也不是一层不变,好的架构是演变而来。要想成为一个好的架构师,学习和实践是我们一直坚持要做的事情,学无止境,学海无涯。

六、参考资料

《深入浅出MyBatis技术原理与实战》书籍

架构师进阶之路——1、持久化框架(一)相关推荐

  1. 大数据架构师进阶之路-技术学习路线

    大数据架构师进阶之路 自大学毕业从事IT行业已有两年有余,虽在这两年一直没有停止学习的脚步,但总是感觉,不成体系,再就是学过的技术长时间不用,也忘记了,写篇博客的目的,是想在工作之余,一是充实自己,将 ...

  2. cs架构用什么语言开发_C、C++、Go 语言、Linux服务器开发高级架构师进阶之路

    C++这门语言从诞生到今天已经经历了将近30个年头.不可否认,它的学习难度都比其它语言较高.而它的学习难度,主要来自于它的复杂性. 现在C++的使用范围比以前已经少了很多,Java.C#.Python ...

  3. 架构师进阶之路,JAVA架构师面试题

    数据结构与算法基础 说一下几种常见的排序算法和分别的复杂度? 用Java写一个冒泡排序算法 ? 描述一下链式存储结构? 如何遍历一棵二叉树? 倒排一个LinkedList? 用Java写一个递归遍历目 ...

  4. Java架构师成长之路

    目录导航 前言 一.源码分析专题 1.1 设计模式详解 1.2 Mybatis源码分析 1.3 Spring5源码分析 二.分布式架构专题 2.1 漫谈分布式架构 2.2 分布式架构的基础 2.3 分 ...

  5. 云架构师进阶攻略(1)

    此文已由作者刘超授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 一.架构的三个维度和六个层面 1.1.三大架构 在互联网时代,要做好一个合格的云架构师,需要熟悉三大架构. 第 ...

  6. 架构师成长之路:如何提升技术掌控力?

    架构师成长之路:如何提升技术掌控力? 简介: 在很多人眼里,架构师就犹如古代的将军一般,既能运筹帷幄决胜千里,又能独闯敌营取人首级,是所有士兵们崇拜的偶像...好了,其实我只是想说:能成为一名优秀的架 ...

  7. 如何成为一名架构师,架构师成长之路(转)

    转自http://blog.csdn.net/fei33423/article/details/61934514 如何成为一名架构师,架构师成长之路 原创 2017年03月13日 22:50:34 3 ...

  8. 开启运维自动化架构师成长之路

    技术的提升仅是量的积累,思想的提升才是质的飞跃! 这句话是我在网上看到认为最有道理的励志语录了,当然互联网IT行业的工作者相对理解的会更加深刻. 以这句话开头引出我将要写的这篇文章.首先,请允许我做一 ...

  9. Linux云计算架构师进阶班-Docker-K8s-Devops-Openstack

    Linux云计算架构师进阶班-Docker-K8s-Devops-Openstack 下载链接: https://pan.baidu.com/s/1l6Xp7_2UsMYfoEKnJAvjUw 提取码 ...

最新文章

  1. C# MD5摘要算法、哈希算法
  2. 【直播提醒】荷小鱼:K12 在线教育应用的开发实践
  3. pc样式在ie8中的bug
  4. Jfinal 显示欢迎页 index.jsp
  5. 浅析Kubernetes Pod重启策略和健康检查
  6. SCRM电商会员管理系统+导购端+商城app+小程序电商+移动端商城+电商web端后台管理+商城前后端系统+移动端商家端+电商app+购物车+订单+商城系统+电商看板+电商后台+优惠券+积分+会员
  7. 简单的java图像裁减
  8. WebService 教程
  9. 计算机文献检索过程,计算机文献检索的基本方法与策略
  10. 7--CAD矩形与正多边形
  11. 应用程序无法正常启动 0x0000005
  12. Unity单机手游逆向破解思路(仅供学习参考,禁止用于非法行为)
  13. android模拟器报错dev kvm is not found
  14. Linux Vim搜索替换命令详解 :%s/foo/bar/g
  15. writeup-passcode
  16. matlab自动变量名,matlab中如何自动给变量命名?
  17. python量化交易--因子选股策略
  18. DSM -- 软件安装
  19. Excel如何批量在空白单元格录入相同内容
  20. 简单工厂/工厂方法/抽象工厂

热门文章

  1. java游戏boss是冰龙_炉石传说冒险模式冰龙区Boss技能及过关卡牌奖励
  2. 电子元器件分销业ERP系统供应链解决方案
  3. linux 选择 平铺 窗口,【如何配置linux 平铺式窗口管理器i3wm?】-看准网
  4. BUAA_OO 第二单元多线程电梯问题作业总结
  5. python进阶练习之——复读机相加
  6. devops数字化管理_可视化DevOps心态
  7. 关于Left Join On的使用
  8. AS如何设置ProgressBar宽度以及实现反向进度条
  9. 微信中那种卡片形式的图文链接是如何制作的
  10. JavaScript特效源码(8、其他特效)