* MyBatis - 2,源码骨架分析

目录:

1、开发重点知识

  • MyBatis快速入门
  • result 与 resultMap
  • 怎么样传递多个参数
  • 获取主键
  • SQL 的参数
  • 代码生成器
  • 关联查询
  • 缓存
  • 与 spring 的集成

2、源码骨架分析

  • 整体架构
  • 日志模块分析
  • 数据源模块分析
  • 缓存模块分析
  • 反射模块分析

3、源码流程分析

  • 流程整体分析
  • 配置加载阶段
  • 代理阶段分析
  • 数据读写阶段

4、知识拾遗

  • 与 spring 的结合源码分析
  • 插件开发
  • 手写 MyBatis

MyBatis - 2,源码骨架分析

1、整体架构

在这里插入图片描述
分层的好处:

  • 架构功能模块
  • 提高开发效率
  • 提高系统伸缩性和性能

外观模式(门面模式)

门面模式:提供了一个统一的接口,用来访问子系统中的一群接口。外观模式定义了一个高层接口,让子系统更容易使用。
在这里插入图片描述
在这里插入图片描述
优点:

  • 使复杂子系统的接口变的简单可用,减少了客户端对子系统的依赖,达到了解耦的效果;遵循了OO原则中的迪米特法则,对内封装具体细节,对外只暴露必要的接口。

使用场景:

  • 一个复杂的模块或子系统提供一个供外界访问的接口
  • 子系统相对独立 ― 外界对子系统的访问只要黑箱操作即可

谈谈设计模式的几个原则

  • 单一职责原则:一个类或者一个接口只负责唯一项职责,尽量设计出功能单一的接口;
  • 依赖倒转原则:高层模块不应该依赖低层模块具体实现,解耦高层与低层。既面向接口编程,当实现发生变化时,只需提供新的实现类,不需要修改高层模块代码;
  • 开放-封闭原则:程序对外扩展开放,对修改关闭;换句话说,当需求发生变化时,我们可以通过添加新模块来满足新需求,而不是通过修改原来的实现代码来满足新需求;
  • 迪米特法则:一个对象应该对其他对象保持最少的了解,尽量降低类与类之间的耦合度;(尽量降低类的访问权限,类之间不要有强)
  • 里氏代换原则:所有引用基类(父类)的地方必须能透明地使用其子类的对象;
  • 接口隔离原则:客户端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上;

2、日志模块分析

2.1

MyBatis没有提供日志的实现类,需要接入第三方的日志组件,但第三方日志组件都有各自的Log级别,且各不相同,而MyBatis统一提供了trace、debug、warn、error四个级别;

自动扫描日志实现,并且第三方日志插件加载优先级如下:slf4J → commonsLoging → Log4J2 → Log4J → JdkLog;

日志的使用要优雅的嵌入到主体功能中;

2.2 适配器模式

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁,将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作;
在这里插入图片描述
适用场景:当调用双方都不太容易修改的时候,为了复用现有组件可以使用适配器模式;在系统中接入第三方组件的时候经常被使用到;

注意:如果系统中存在过多的适配器,会增加系统的复杂性,设计人员应考虑对系统进行重构;
在这里插入图片描述

2.3 代理模式

定义:给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用;

目的:
(1)通过引入代理对象的方式来间接访问目标对象,防止直接访问目标对象给系统带来的不必要复杂性;
(2)通过代理对象对原有的业务增强;

2.4 代码梳理

集成slf4j、log4j、log4j2、jdkLog、

自定义一个Log 接口:(适配器模式)
	创建一个实现Log接口的MyBatis自己的Slf4jImpl实现类,
	创建一个实现Log接口的slf4j的Slf4jLoggerImpl的实现类

LogFactory	工厂模式
	// 关键成员变量
	private static Constructor<? extends Log> logConstructor;
	
	使用静态代码块,设置集成的外部日志框架的加载顺序
	static{
		tryImplementaion(() -> {useSlf4jLogging();});
		。。。
	}
	
	private static void tryImplementation(Runnable runable){
		if(logConstructor == null) {
			try {
				runable.run();
			}catch() {
				// ignore
			}
		}
	}
	
	public static synchronized void useSlf4jLogging() {
		setImplementation(org.apache.ibatis.logging.log4j.Log4jImpl.class);
	}
	
	private static void setImplementation(Class<? extends Log> implClass) {
		try {
			Constructor<? extends Log> candidate = implClass.getConstructor(String.class);
			Log log = candidata.newInstance(LogFactory.class.getName());
			if (log.isDebugEnable()) {
				log.debug("Logging initialized using ");
			}
			logConstructor = candidate;
		} catch (Throwable t) {
			throw new LogException("");
		}
	}
	
	private LogFactory() {
		// disable construction
	}	

3、数据源模块分析

3.1 基础支撑层源码分析 创建一个数据源的难点

常见的数据源组件都实现了javax.sql.DataSource接口;
MyBatis不但要能集成第三方的数据源组件,自身也提供了数据源的实现;
一般情况下,数据源的初始化过程参数较多,比较复杂;

3.2 工厂模式uml类图

在这里插入图片描述

3.3 数据源模块类图

在这里插入图片描述

3.4 为什么要使用工厂模式

在这里插入图片描述

4、缓存模块分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

锁粒度的问题 粗粒度锁

在这里插入图片描述

锁粒度的问题 细粒度锁(按key)

在这里插入图片描述

CacheKey解读

MyBatis中涉及到动态SQL的原因,缓存项的key不能仅仅通过一个String来表示,所以通过CacheKey来封装缓存的Key值,CacheKey可以封装多个影响缓存项的因素;判断两个CacheKey是否相同关键是比较两个对象的hash值是否一致;

在这里插入图片描述

5、反射模块分析

orm框架查询数据过程

在这里插入图片描述

反射的核心类

在这里插入图片描述
MetaObject:封装了对象元信息,包装了MyBatis中五个核心的反射类。也是提供给外部使用的反射工具类,可以利用它可以读取或者修改对象的属性信息;
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值