本书从MyBatis源码的角度分析Mapper绑定过程、SqlSession操作数据库原理、插件实现原理等,同时介绍一些MyBatis的高级用法,并挖掘MyBatis源码中使用的设计模式。 本书共13章,分为MyBatis 3源码篇和MyBatis Spring源码篇。第1~11章介绍MyBatis核心源码,从源码的角度分析MyBatis的实现原理,并介绍一些MyBatis的高级用法。MyBatis大多数情况下会与Spring整合使用,第12~13章介绍MyBatis Spring的实现原理,并分析MyBatis Spring模块的核心代码。 本书适合掌握了MyBatis的基本用法并希望了解MyBatis底层实现的Java开发人员、架构师以及对Java开源项目感兴趣的读者阅读。
本书从MyBatis源码的角度分析了Mapper绑定过程、SqlSession操作数据库原理、插件实现原理等,同时介绍一些MyBatis的高级应用,挖掘MyBatis源码中使用的设计模式。本书适合希望
了解MyBatis底层实现的Java开发人员、架构师以及对Java开源项目感兴趣的所有读者阅读参考。
前 言
在写作本书时,SSM(Spring、Spring MVC和MyBatis)框架已经成为很多互联网公司的标配。笔者最早接触MyBatis框架是在2014年,当时接手的是一个非常成熟的网上银行系统,项目中使用的持久层框架就是MyBatis的前身iBatis框架。后来换了两份工作,新的公司也都选择MyBatis作为持久层框架。从iBatis过渡到MyBatis框架几乎不需要任何学习成本,MyBatis延续了iBatis简单易用的特点,优化了SQL配置方式,引用OGNL表达式来支持动态SQL配置,使得动态SQL配置更加优雅,而且更容易理解。在笔者看来,MyBatis相对于iBatis框架最大的创新是引入了SQL Mapper的概念。我们可以将XML文件中的SQL配置与一个Java接口进行绑定,SQL配置的命名空间对应Java接口的完全限定名,而具体的每个SQL语句的配置对应Java接口中的一个方法,建立绑定后,可以通过调用Java接口中定义的方法来执行XML文件中配置的SQL语句。
MyBatis作为持久层框架,以其小巧轻便、SQL可配置、使用简单等特点深受广大Java开发者喜爱。然而大多数开发人员对MyBatis框架的理解仅局限于使用,并不理解框架底层的实现原理。作为一名开发人员,阅读开源框架的源码,可以学习源码中对设计模式及面向对象设计原则的应用,有助于提升自身编码能力。笔者在工作之余,深入研究了MyBatis框架的源码,本书将会从源码的角度分析MyBatis框架各个特性的实现原理。
阅读准备
在阅读本书之前,读者需要准备如下开发环境:
? JDK1.8或以上版本
? Apache Maven构建工具
? IntelliJ IDEA 开发工具
? Git版本控制工具
内容概要
本书主要分为两篇:第1篇为MyBatis 3源码篇(第1~11章),主要介绍MyBatis框架各个特性的源码实现;第2篇章为MyBatis Spring源码篇(第12~13章),主要介绍MyBatis框架与Spring框架整合的原理及MyBatis Spring模块的实现细节。下面是本书的内容大纲。
第1章 搭建MyBatis源码环境
主要介绍如何搭建MyBatis源码调试环境,包括MyBatis框架源码获取途径、如何导入集成开发工具以及如何运行MyBatis源码中的测试用例。
第2章 JDBC规范详解
MyBatis框架是对JDBC轻量级的封装,熟练掌握JDBC规范有助于理解MyBatis框架实现原理。本章将详细介绍JDBC规范相关细节,已经全面掌握JDBC规范的读者可以跳过该章。
第3章 MyBatis常用工具类
介绍MyBatis框架中常用的工具类,避免读者因对这些工具类的使用不熟悉而导致对框架主流程理解的干扰,这些工具类包括MetaObject、ObjectFactory、ProxyFactory等。
第4章 MyBatis核心组件介绍
介绍MyBatis的核心组件,包括Configuration、SqlSession、Executor、MappedStatement等,包括这些组件的作用及MyBatis执行SQL语句的核心流程。
第5章 SqlSession的创建过程
主要介绍SqlSession组件的创建过程,包括MyBatis框架对XPath方式解析XML封装的工具类、MyBatis主配置文件解析生成Configuration对象的过程。
第6章 SqlSession执行Mapper过程
本章介绍Mapper接口注册的过程、SQL配置转换为MappedStatement对象并注册到Configuration对象的过程。除此之外,本章还将介绍SqlSession对象执行Mapper的过程。
第7章 MyBatis缓存
本章首先介绍MyBatis一级缓存和二级缓存的使用细节,接着介绍一级缓存和二级缓存的实现原理,最后介绍MyBatis如何整合Redis作为二级缓存。
第8章 MyBatis日志实现
基于Java语言的日志框架比较多,比较常用的有Logback、Log4j等,本章介绍Java的日志框架发展史,并介绍这些日志框架之间的关系,最后介绍MyBatis自动查找日志框架的实现原理。
第9章 动态SQL实现原理
本章主要介绍MyBatis动态SQL的使用、动态SQL配置转换为SqlSource对象的过程以及动态SQL的解析原理,最后从源码的角度分析动态SQL配置中#{}和${}参数占位符的区别。
第10章 MyBatis插件原理及应用
本章介绍MyBatis插件的实现原理,并以实际的案例介绍如何自定义MyBatis插件。在本章中将会实现两个MyBatis插件,分别为分页查询插件和慢SQL统计插件。
第11章 MyBatis级联映射与懒加载
本章介绍MyBatis中一对一、一对多级联映射和懒加载机制的使用细节,并介绍级联映射和懒加载的源码实现。
第12章 MyBatis与Spring整合案例
在介绍MyBatis框架与Spring整合原理之前,需要了解MyBatis整合Spring的基本配置,本章以一个用户注册RESTful接口案例作为MyBatis框架与Spring框架整合的最佳实践。
第13章 MyBatis Spring的实现原理
首先介绍Spring框架中的一些核心概念和Spring IoC容器的启动过程,接着介绍MyBatis和Spring整合后动态代理产生的Mapper对象是如何与Spring Ioc容器进行关联的,最后介绍MyBatis整合Spring事务管理的实现原理。
随书源码
本书相关源码托管在Github上,读者可以从Github仓库获取随书源码。
源码地址:https://github.com/rongbo-j/mybatis-book。
图书勘误
由于个人能力有限,书中可能有表述不到位或者对知识点理解欠妥的地方,欢迎读者批评指正。若有任何疑问,均可以在随书源码Github仓库上提交。
勘误地址:https://github.com/rongbo-j/mybatis-book/issues。
致谢
本书从写作到完稿用了一年多时间,这个过程对于笔者来说是一个极大的考验。作为一名程序员,只有不断地提升,才会觉得充实。把大量的时间用在写作上,时常会因为没有摄入新知识而恐慌,感谢在本书写作过程中家人对我精神上的支持。另外,特别感谢夏毓彦老师和清华大学出版社的工作人员,有你们的帮助才有本书的顺利出版。
著 者
2019年5月
江荣波,JAVA高级工程师,参与过网上银行、短信平台、渠道整合平台开发等大型Java EE项目及多款金融类App产品开发。出版图书《AngularJS入门与进阶》。
目 录
第1篇 MyBatis 3源码
第1章 搭建MyBatis源码环境 3
1.1 MYBATIS 3简介 3
1.2 环境准备 4
1.3 获取MYBATIS源码 4
1.4 导入MYBATIS源码到IDE 6
1.5 HSQLDB数据库简介 9
1.6 本章小结 11
第2章 JDBC规范详解 13
2.1 JDBC API简介 13
2.1.1 建立数据源连接 14
2.1.2 执行SQL语句 15
2.1.3 处理SQL执行结果 16
2.1.4 使用JDBC操作数据库 16
2.2 JDBC API中的类与接口 17
2.2.1 java.sql包详解 17
2.2.2 javax.sql包详解 20
2.3 CONNECTION详解 24
2.3.1 JDBC驱动类型 24
2.3.2 java.sql.Driver接口 26
2.3.3 Java SPI机制简介 27
2.3.4 java.sql.DriverAction接口 29
2.3.5 java.sql.DriverManager类 29
2.3.6 javax.sql.DataSource接口 31
2.3.7 使用JNDI API增强应用的可移植性 32
2.3.8 关闭Connection对象 34
2.4 STATEMENT详解 35
2.4.1 java.sql.Statement接口 35
2.4.2 java.sql.PreparedStatement接口 39
2.4.3 java.sql.CallableStatement接口 43
2.4.4 获取自增长的键值 44
2.5 RESULTSET详解 45
2.5.1 ResultSet类型 45
2.5.2 ResultSet并行性 46
2.5.3 ResultSet可保持性 46
2.5.4 ResultSet属性设置 47
2.5.5 ResultSet游标移动 47
2.5.6 修改ResultSet对象 48
2.5.7 关闭ResultSet对象 50
2.6 DATABASEMETADATA详解 51
2.6.1 创建DatabaseMetaData对象 51
2.6.2 获取数据源的基本信息 51
2.6.3 获取数据源支持特性 53
2.6.4 获取数据源限制 53
2.6.5 获取SQL对象及属性 54
2.6.6 获取事务支持 54
2.7 JDBC事务 54
2.7.1 事务边界与自动提交 55
2.7.2 事务隔离级别 55
2.7.3 事务中的保存点 56
2.8 本章小结 57
第3章 MyBatis常用工具类 58
3.1 使用SQL类生成语句 58
3.2 使用SCRIPTRUNNER执行脚本 64
3.3 使用SQLRUNNER操作数据库 67
3.4 METAOBJECT详解 71
3.5 METACLASS详解 72
3.6 OBJECTFACTORY详解 73
3.7 PROXYFACTORY详解 74
3.8 本章小结 75
第4章 MyBatis核心组件介绍 76
4.1 使用MYBATIS操作数据库 76
4.2 MYBATIS核心组件 80
4.3 CONFIGURATION详解 82
4.4 EXECUTOR详解 88
4.5 MAPPEDSTATEMENT详解 90
4.6 STATEMENTHANDLER详解 92
4.7 TYPEHANDLER详解 94
4.8 PARAMETERHANDLER详解 97
4.9 RESULTSETHANDLER详解 98
4.10 本章小结 100
第5章 SqlSession的创建过程 101
5.1 XPATH方式解析XML文件 101
5.2 CONFIGURATION实例创建过程 104
5.3 SQLSESSION实例创建过程 108
5.4 本章小结 109
第6章 SqlSession执行Mapper过程 110
6.1 MAPPER接口的注册过程 110
6.2 MAPPEDSTATEMENT注册过程 114
6.3 MAPPER方法调用过程详解 119
6.4 SQLSESSION执行MAPPER过程 126
6.5 本章小结 130
第7章 MyBatis缓存 131
7.1 MYBATIS缓存的使用 131
7.2 MYBATIS缓存实现类 132
7.3 MYBATIS一级缓存实现原理 135
7.4 MYBATIS二级缓存实现原理 138
7.5 MYBATIS使用REDIS缓存 142
7.6 本章小结 145
第8章 MyBatis日志实现 146
8.1 JAVA日志体系 146
8.2 MYBATIS日志实现 149
8.3 本章小结 155
第9章 动态SQL实现原理 156
9.1 动态SQL的使用 156
9.2 SQLSOURCE与BOUNDSQL详解 159
9.3 LANGUAGEDRIVER详解 161
9.4 SQLNODE详解 164
9.5 动态SQL解析过程 169
9.6 从源码角度分析#{}和${}的区别 179
9.7 本章小结 182
第10章 MyBatis插件原理及应用 184
10.1 MYBATIS插件实现原理 184
10.2 自定义一个分页插件 193
10.3 自定义慢SQL统计插件 198
10.4 本章小结 200
第11章 MyBatis级联映射与懒加载 201
11.1 MYBATIS级联映射详解 201
11.1.1 准备工作 201
11.1.2 一对多关联映射 205
11.1.3 一对一关联映射 206
11.1.4 Discriminator详解 209
11.2 MYBATIS懒加载机制 210
11.3 MYBATIS级联映射实现原理 212
11.3.1 ResultMap详解 212
11.3.2 ResultMap解析过程 213
11.3.3 级联映射实现原理 218
11.4 懒加载实现原理 225
11.5 本章小结 230
第2篇 MyBatis Spring源码
第12章 MyBatis与Spring整合案例 233
12.1 准备工作 233
12.2 MYBATIS与SPRING整合 234
12.3 用户注册案例 236
12.4 本章小结 239
第13章 MyBatis Spring的实现原理 240
13.1 SPRING中的一些概念 240
13.2 SPRING容器启动过程 243
13.3 MAPPER动态代理对象注册过程 244
13.4 MYBATIS整合SPRING事务管理 248
13.5 本章小结 253