(/≧▽≦)/~┴┴ 嗨~我叫小奥 ✨✨✨
👀👀👀 个人博客:小奥的博客
👍👍👍:个人CSDN
⭐️⭐️⭐️:传送门
🍹 本人24应届生一枚,技术和水平有限,如果文章中有不正确的内容,欢迎多多指正!
📜 欢迎点赞收藏关注哟! ❤️
本博文主要是分享自己学习MyBatis源码的一些记录,会参考大量的博文和一些书籍,链接会放在文末。
MyBatis版本:3.5.14
下载源来自Github,fork到自己仓库中,然后clone即可。
如下图,是MyBatis源码的目录结构下的所有包。
其中,各个包的内容简介如下:
包名称 | 包内内容简介 |
---|---|
annotation | 注解目录。包括所有的注解。如@SELECT,@UPDATE等 |
binding | Mapper类的实例反射生成工具目录 |
builder | 主要是注解,mapper和SqlSuorce的构造器及转换器 |
cache | Mybatis内部缓存接口。实现了一些特定的缓存策略。FifoCache,LruCache,BlockingCache,LoggingCache等 |
cursor | 默认的游标处理类 |
dataSource | 数据源工厂类及实现。实现类包括JndiDataSourceFactory、PooledDataSourceFactory、UnpooledDataSourceFactory。 数据源实现类: UnpooledDataSource、PooledDataSource |
exceptions | Mybatis自定义的三个异常类。ExceptionFactory、PersistenceException、TooManyResultsException、IbatisException。都继承自RuntimeException |
executor | 执行器相关包。包括Key生成器、加载器(包括Cglib、Javassist的代理,结果加载器)、参数处理器接口、结果处理器、结果集(resultSet)处理器、Statement处理器(实现类:BaseStatementHandler、CallableStatementHandler、PreparedStatementHandler、RoutingStatementHandler、SimpleStatementHandler)、执行器(SimpleExecutor、ReuseExecutor、CachingExecutor、BatchExecutor、BaseExecutor) |
io | 主要是定义的几个VFS(VFS、DefaultVFS、ClassLoaderWrapper) |
jdbc | 与Sql相关的操作。如Sql运行器,脚本运行器和Sql封装类等 |
lang | 指定是用java7还是java8的API的注解.UsesJava7、UsesJava8 |
logging | 各个类型的日志适配器,都实现了Log接口。StdOutImpl、Slf4jImpl、NoLoggingImpl、Log4j2Impl、Log4jImpl、Jdk14LoggingImpl、BaseJdbcLogger、JakartaCommonsLoggingImpl |
mapping | 主要是接口参数,sql和返回结果的映射类,主要类包括:MappedStatement,ParameterMap,ParameterMapping,ResultMap,ResultMapping,BoundSql,SqlSource等类 |
parsing | 变量解析.如解析${},#{}等 |
plugin | 主要包含插件的定义接口。如Interceptor,Plugin,InterceptorChain等 |
reflection | 主要是一些反射操作的工具方法和对象工厂类,以及一些常用的包装类,如BaseWrapper,BeanWrapper,CollectionWrapper,MapWrapper,ObjectWrapper。 |
scripting | 执行驱动和动态Sql解析 |
session | 主要是SqlSession和SqlSessionFactory |
transaction | 主要是mybatis简单封装的jdbc事务操作类 |
type | 各个类型数据的处理器。用于动态的设置参数和转换数据。如IntegerTypeHandler用来处理Integer类型的值的set和get操作。除了八大基本类型。还有常用的集合及Map类型,还增加了各种时间类型的处理器 |
MyBatis的整体架构分为三层:基础支持层、核心处理层和接口层。
基础支持层,包含整个 MyBatis 的基础模块,这些模块为核心处理层的功能提供了良好的支撑
核心处理层实现了MyBatis的核心处理流程,其中包括MyBatis的初始化以及完成一次数据库操作涉及的全部流程。
在 MyBatis 初始化过程中,会加载 mybatis-config.xml 配置文件、映射配置文件以及 Mapper 接口中的注解信息,解析后的配置信息会形成相应的对象并保存到 Configuration 对象中。之后,利用该 Configuration 对象创建 SqlSessionFactory 对象。待 MyBatis 初始化之后,开发人员可以通过初始化得到 SqlSessionFactory 创建 SqlSession 对象并完成数据库操作。
MyBatis实现动态SQL功能,提供了多种动态SQL语句对应的节点。如
MyBatis 中的 scripting 模块会根据用户传入的实参,解析映射文件中定义的动态 SQL 节点,并形成数据库可执行的 SQL 语句。之后会处理 SQL 语句中的占位符,绑定用户传入的实参。
SQL 语句的执行涉及多个组件,其中比较重要的是 Executor 、StatementHandler 、ParameterHandler 和 ResultSetHandler。
Executor 主要负责维护一级缓存和二级缓存,并提供事务管理的相关操作,它会将数据库相关操作委托给StatementHandler 完成。StatementHandler 首先通过 ParameterHandler 完成 SQL 语句的实参绑定;然后通过 java.sql.Statement 对象执行 SQL 语句并得到结果集;最后通过 ResultSetHandler 完成结果集的映射,得到结果对象并返回。
用户可以通过添加自定义插件的方式对 MyBatis 进行扩展。用户自定义插件也可以改变 MyBatis 的默认行为,例如,我们可以拦截 SQL 语句并对其进行重写。由于用户自定义插件会影响 MyBatis 的核心行为,在使用自定义插件之前,开发人员需要了解 MyBatis 内部的原理,这样才能编写出安全、高效的插件。
下图展示了MyBatis执行一条SQL语句的大致过程:
接口层相对简单,其核心是SqlSession接口,该接口中定义了MyBatis暴露给应用程序调用的Api,也就是上层应用与MyBatis交互的桥梁。接口层在收到调用请求时,会调用核心处理层的相应模块来完成具体的数据库操作。
MyBatis的代码并不是很多,相对于源码阅读入门的同学来说还是比较简单的,我会按照以上三个模块(基础支持层 ==> 核心处理层 ==> 接口层)进行逐步分析。