欢迎关注公众号 【11来了】 ,持续 MyBatis 源码系列内容!
在我后台回复 「资料」 可领取
编程高频电子书
!
在我后台回复「面试」可领取硬核面试笔记
!文章导读地址:点击查看文章导读!
感谢你的关注!
MyBatis 源码系列文章:
(一)MyBatis 源码如何学习?
(二)MyBatis 运行原理 - 读取 xml 配置文件
(三)MyBatis 运行原理 - MyBatis 的核心类 SqlSessionFactory 和 SqlSession
(四)MyBatis 运行原理 - MyBatis 中的代理模式
(五)MyBatis 运行原理 - 数据库操作最终由哪些类负责?
(六)MyBatis 运行原理 - 执行 Mapper 接口的方法时,MyBatis 怎么知道执行的哪个 SQL?
(七)MyBatis 运行原理 - JVM 级别缓存能力设计:MyBatis 的一、二级缓存如何设计?
MyBatis 设计的目的是将 SQL 执行的相关操作进行抽象封装,当研发人员需要操作数据库时,不需要重复去编写建立连接、执行 SQL、返回结果等代码,提升研发效率;但作为组件,MyBatis 为了不对业务造成入侵,一定会只对通用能力进行封装,那么就会在一些个性化场景中没有较好的支撑, 在不增加 MyBatis 源码复杂度的情况下,如何提供更个性化的业务支撑呢?
答案: 预留扩展点
组件通常都会预留出 扩展点 ,来供研发人员对原流程进行扩展和改写,而且这些扩展点往往都是在组件的不同时期执行的,因此想要使用好扩展点,我们还必须要熟悉对应组件的执行流程
常见的有:MyBatis 中的拦截器、Spring 中的各个扩展点等等,当有一些个性化的需求,例如分库分表、分页查询、黑名单 SQL、应用层慢 SQL 统计等等都可以利用 MyBatis 中的插件来实现,
接下来就会介绍一下 MyBatis 中插件的设计原理,可以借鉴于自己日常项目、组件的开发
背景知识
1、MyBatis 插件的使用限制
MyBatis 的插件只能对 4 种组件的方法进行拦截:
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) 主要用于sql重写
ParameterHandler (getParameterObject, setParameters) 用于参数处理
ResultSetHandler (handleResultSets, handleOutputParameters) 用于结果集二次处理
StatementHandler (prepare, parameterize, batch, update, query) 用于 JDBC 层的控制
2、4 种组件介绍
MyBatis 插件提供了对 4 种组件的拦截,先简单介绍 4 种组件:
- Executor:MyBatis 核心接口之一,定义了数据库的基本操作,最终数据库的操作都是交给 Executor 来完成的
- ParameterHandler:为 SQL 语句的占位符绑定实参数据
- ResultSetHandler:将从数据库中查询到的结果集进行处理
- StatementHandler:MyBatis 核心接口之一,在 Executor 内部会通过 StatementHandler 去完成 SQL 的执行
接下来主要介绍一下 StatementHandler 这个接口,后边会基于该接口实现一个 应用层的慢 SQL 查询插件
- StatementHandler 接口作