作者笔记仓库:https://github.com/seazean/javanotes
欢迎各位关注我的笔记仓库,clone 仓库到本地后使用 Typora 阅读效果更好。
笔记内容参考视频:https://www.bilibili.com/video/BV1mW411M737?p=71
一、运行机制
MyBatis 运行过程:
-
加载 MyBatis 全局配置文件,通过 XPath 方式解析 XML 配置文件,首先解析核心配置文件,
标签中配置属性项有 defaultExecutorType,用来配置指定 Executor 类型,将配置文件的信息填充到 Configuration对象。最后解析映射器配置的映射文件,并
构建 MappedStatement 对象填充至 Configuration,将解析后的映射器添加到 mapperRegistry 中,用于获取代理
-
创建一个 DefaultSqlSession 对象,根据参数创建指定类型的 Executor,二级缓存默认开启,把 Executor 包装成缓存执行器
-
DefaulSqlSession 调用 getMapper(),通过 JDK 动态代理获取 Mapper 接口的代理对象 MapperProxy
-
执行 SQL 语句:
- MapperProxy.invoke() 执行代理方法,通过 MapperMethod 判断执行的是增删改查中的哪个方法
- 获取执行者对象 MappedStatement,Executor 调用 executor 开始驱动方法的执行
- 首先通过 CachingExecutor 去二级缓存查询,查询不到去一级缓存查询,最后去数据库查询并放入一级缓存
- Configuration 对象根据 标签的 statementType 属性,根据属性选择创建哪种对象
- 判断 BoundSql 是否被创建,没有创建会重新封装参数信息到 BoundSql
- StatementHandler 的构造方法中,创建了 ParameterHandler 和 ResultSetHandler 对象
interceptorChain.pluginAll(statementHandler)
:拦截器链
prepareStatement()
:通过 StatementHandler 创建 JDBC 原生的 Statement 对象
getConnection()
:获取 JDBC 的 Connection 对象
handler.prepare()
:初始化 Statement 对象
instantiateStatement(Connection connection)
:Connection 中的方法实例化对象
- 获取普通执行者对象:
Connection.createStatement()
- 获取预编译执行者对象:
Connection.prepareStatement()
handler.parameterize()
:进行参数的设置
ParameterHandler.setParameters()
:通过 ParameterHandler 设置参数
typeHandler.setParameter()
:底层通过 TypeHandler 实现
StatementHandler.query()
:封装成 JDBC 的 PreparedStatement 执行 SQL
resultSetHandler.handleResultSets(ps)
:通过 ResultSetHandler 对象封装结果集
localCache.putObject(key, list)
:放入本地缓存
return list.get(0)
:返回结果集的第一个数据
