前言
相对于 Spring 框架的源码,或者基于 Spring 的 SpringBoot、Spring Clound ,MyBatis 简单些,自己能跟得上,在学习上也能获得更多的正反馈,而且一些框架设计理念、设计模式也能更好的掌握,为学习 Spring 等 Java 界一哥框架打下基础。
整体架构
因为我是跟着小傅哥的手写 MyBatis 写过一部分的源码,感觉上能入手真正的源码解析了。但是还不是我自己的东西,所以这是我将 MyBatis 源码转换为自己东西的必要步骤。
《MyBatis 技术内幕》中的图
自己去 GitHub 上拉的 MyBatis 源码:代码结构图
基础支持层
包含整个 MyBatis 的基础模块,这些模板为核心处理层提供了强有力的支撑。而且 MyBatis 是纯 Java 写的,比如 Java 动态代理、Java 反射都得到了良好的运用。
- 反射模块
对应 reflection 包,对于我们这种基础的开发人员来说,写出高质量的反射代码是很难的,所以 MyBatis 中专门对反射进行了良好的封装,提供了更加简洁易用的 API。
- 类型模块
type 包下
MyBatis 为简化配置文件提供了别名机制,该机制是类型转换模块的主要功能之一。
实现 JDBC 类型与 Java 类型之间的转换,该功能在为 SQL 语句绑定实参以及映射查询结果集都会涉及:
- SQL 语句绑定实参时,会将数据由 Java 类型转换成 JDBC 类型
- 在映射结果集时,会将数据由 JDBC 类型转换成 Java 类型
- IO 模块
对应 io 包,主要就是对类加载器进行封装,确定类加载器的使用顺序,并提供了加载类文件以及其他资源文件的功能。
- 解析器模块
对应 parsing 包
- 提供了对 XPath 的封装,为 MyBatis 初始化时解析 mybatis-config.xml 配置文件以及映射配置文件提供支持。
- 为处理动态 SQL 语句中的占位符提供支持
- 数据源模块
对应 datasource 包。
目前提供了很多优秀的数据源,比如 Druid ,里面提供了很多功能:连接池功能、状态检测功能等。
MyBatis 自身也提供了相应的功能,比如:无池化、有池化技术
在 xml 配置文件中使用 就可以使用 MyBatis 自身的数据源池化技术。
- 事务模块
对应 transaction 包。
MyBatis 对数据库中的事务进行了抽象,自身提供了相应的事务接口和简单实现。在实际开发中一般都是和 Spring 集成,然后交由 Spring 框架管理事务,比如单体项目中使用 @Transactional 注解
- binding 模块
对应 binding 包。
里面主要是使用 Java 动态代理实现对 Mapper 接口的代理,所以使得我们开发员人不用自己定义 Mapper 接口 的实现。
- 注解模块
对应 annotation 包。
Java 注解更加方便流行,所以 MyBatis 也提供了注解的方式,比如我们可以直接在 Mapper 文件的方法上使用注解代替 xml 文件中的 SQL 配置。
不过个人感觉还是在 xml 中编写 SQL 来得更实在,比如复杂的 SQL 在 xml 中更好编写和易读,都在一个 xml 文件中也更好管理。
- 日志模块和异常模块
分别在 logging 、exceptions 包。
这两个对于真实的业务实现来说没啥用,就是没有他们两个代码也能跑。但是从代码维护性、健壮性、程序整体架构上是必不可少的。想必没有打日志或者忘记打日志出现在线上环境的时候,都是无比头疼的吧。
异常模块就是统一封装异常,其中 MyBatis 专门定义了 PersistenceException(大多数是和 Mapper 接口与 xml 配置文件相关) 和 TooManyResultsException(定义了 Map 接收,但是返回多条数据,相信这个报错都遇到过吧)。
总结
上面基本上是总的提纲挈领,里面不仅代码写的漂亮,设计模式运用的也是炉火纯青:比如:
- type 包,类型模块。对策略模式完美使用。解析 SQL 按照不同的策略封装不同的类型处理器
- binding 包,完美实现了 Java 动态代理,即是平时学习的代理模式
- 还有里面涉及到生成对象的,都使用到了工厂模式,比如 Transaction 包、DataSource 包
等等还有很多。
基本上要学习源码,除了基本的语法知识之外,还要了解其他比较通用的知识,比如设计模式。任何一个框架都会使用设计模式,来帮助这个框架达成可读、易维护、健壮、可扩展的目的。