MyBatis 源码分析-end-知识点总结
Version :
MyBatis : 3.5.5
项目地址 :MyBatis-source-learn
- PS: 若文章字体偏大或者偏小,建议通过 ctrl键+鼠标滑轮 进行修改,以提升阅读效果.(带来不便,请谅解!)
本文将分享自己的源码阅读技巧以及MyBatis 相关知识的总结.
- PS: 若文章字体偏大或者偏小,建议通过 ctrl键+鼠标滑轮 进行修改,以提升阅读效果.(带来不便,请谅解!)
源码如何阅读
我自己的阅读方式是: 通过maven 将 mybatis-source.jar 下载下来,然后 解压到文件夹mybatis-source中, 再利用IDEA 中project structure -> library 更换source 文件的方式将 maven下载的jar包换掉,然后自己就可以愉快的阅读源码, 加注释,自己进行修改了.
注意: 由于源码不是自己编译的,所以在添加注释时,需要与源码原来的行号保持对齐,不然就等着debug时候哭
Mybatis 内容整理
生成MappedStatement
**原文地址: ** MyBatis 源码分析-01-解析SQL
解析XML 生成 mappedStatement:
解析xml 文件
-> 解析 <mapper/> 标签
-> 解析 单个节点
->生成SQL (1.处理方法参数) 生成类似于 select * from blog where id =?
-> 处理主键
-> 处理 statement 类型
-> 处理 resultset
-> 生成 mappedstatement
解析Annotation 生成mappedstatement:
遍历接口 的每一个方法 ,通过解析注解的形式生成mappedstatement
获取SqlSession
原文地址: MyBatis 源码分析-02-生成实例MapperProxy 代理对象
1. 创建事务 transaction( 利用 TransactionFactory 创建)
2. 创建 Executor ( 默认SimpleExecutor -> CachingExecutor (原因 :mybatis中cacheEnabled的默认值为true))
3. 创建sqlsession
生成MapperProxy
没啥好说的, 利用JDK 代理生成 MapperProxy.
MyBatis 查询流程:
**原文地址: **MyBatis 源码分析-03 - MyBatis 方法执行流程分析
- MyBatis 在不修改默认配置项时, 其查询顺序为:
二级缓存 CachingExecutor.cache -> 一级缓存 Executor.localCache -> DB
- 一级缓存 LocalCache: localCacheScope= session( default), 建议修改为 statement ,session 存在脏读现象
- 二级缓存 Cache: cacheEnabled=true(default), 对应xxxMapper.xml 添加
即可使用,使用二级缓存,可以有效避免在单表查询时出现的脏读现象,但是在多表查询时,极大可能出现脏数据,存在缺陷.
Mybatis 生成 statement:
**原文地址: **MyBatis 源码分析-04-MyBatis Statement 的生成流程
流程描述:
1. 生成 statementHandelr(resultSethandler,)
1. StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
2. 生成 Statement
1. stmt = prepareStatement(handler, ms.getStatementLog());//对statement 进行处理,绑定参数到sql中
1. 获取Connection : getConnection(statementLog)
2. 生成Statement , 绑定 方法参数
1. 实例化Statement: stmt = handler.prepare(connection, transaction.getTimeout());
结果: stmt = com.mysql.cj.jdbc.ClientPreparedStatement: select * from Blog where id = ** NOT SPECIFIED **
2. 处理方法参数 : handler.parameterize(stmt);// 处理参数 绑定 sql - java type
结果: stmt= com.mysql.cj.jdbc.ClientPreparedStatement: select * from Blog where id = 1
Mybatis 处理ResultSet:
原文地址:MyBatis 源码分析-05 - MyBatis ResultSet 处理流程分析
处理行数据rowValue 流程:
1 . 实例化 resultObject
- 将 数据表字段与JavaBean 属性名称 相互绑定
- 利用 反射生成 setter 方法 进行赋值
MyBatis 一级缓存:
- MyBatis一级缓存的生命周期和SqlSession一致。
- MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。
- MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement。
Mybatis 二级缓存:
在分布式系统中不建议使用, 缓存可以通过redis 等形式实现, 因为 二级缓存在 多表联合查询时会存在脏读现象
参考:
https://tech.meituan.com/2018/01/19/mybatis-cache.html