这篇文章用来自己梳理mybatis的相关消息:没有任何学习意义
1. mybatis的解析过程
主要类:XMLconfigBuilder
第一步:解析属性 properties
注意的地方:覆盖优先级,<property>
标签属性最低,resource或者url的优先级第二,通过属性传递来的优先级最高
第二步:解析配置属性
利用包装的反射来验证Configuration是否有这个属性。
第三步:自定义文件系统
第四步:自定义日志系统
第五步:别名补充
第六步:补充插件
第七步:自定义的对象工厂
第八步:自定义的对象包装工厂 DefaultObjectWrapperFactory
第九步:自定义反射工厂
第十步:设置其他的属性
第十一步:配置环境->数据源
第十二补:数据库厂商id
第十三部:补充typehandler
第十四不:解析mapper文件
2. mybtais的执行过程
打开SqlSession:
- 建立excutor执行器,更据configuration的cacheEabled参数,是否装饰执行器成CachingExcutor执行器。这里就是一级缓存。
- 将插件在executor执行一遍
获取对应的mapper
- 从configuration对象中获取对应的mapperFactory。进行实例化 共享mapperfactory 但是每次是从更据sqlSession实例化新的mapper代理对象。所以mapperfactory里面的mapperMethodInvoker也是共享的。
mapper的执行
一阶段:更据方法名找到待执行的mappedStatment
- 生产对应的mappermethodInoker,这里我们看我们常用的那个。PlainMethodInvoker实现。实际上是生产对应的MapperMethod
- 构建mapperMethod主要就是构建SqlCommand和MethodSignature。sql command由用一个String(命名空间)和sql类型组成。MethodSignature则是你能从方法上获得得信息( 1。返回类型 2.特殊参数的下标 3.ParamNameResolver)
- 返回类型 returnsMany;
- ParamNameResolver的构建
- 将方法参数映射成一个map,key 为参数的下标,value为: 更据优先级:1Param注解的值 or (有条件的)参数的实际名称or添加时map的大小。这里会忽略(RowBounds. 和ResultHandler)
二阶段:执行
也就是mapperMethod的执行 public Object execute(SqlSession sqlSession, Object[] args)
- insert
- 参数的转换,即把实际的参数转化出来,就是上述ParamNameResolver的事
- 情况1:都为0直接返回null
- 情况2:没有参数注解且参数的数量为1 如果是集合则进行包装
- 情况3:多个参数或者有参数注解 返回一个ParamMap (key 为方法中mybatis眼里的参数名,value为参数对象)
- 执行
- 这里其实回到了sqlSession里的执行。带着一个映射后的参数。利用sqlSession带的executor进行执行,key找到MappedStatement(在解析配置文件中已经完成,后面简称为ms)。后面就是执行器的过程。详情请看下面的执行器的执行过程
- 参数的转换,即把实际的参数转化出来,就是上述ParamNameResolver的事
- update
- delete
- select
执行器执行阶段
执行器好像默认带了缓存。在BaseExecutor中,mybatis有几个执行器,以simperExecutor进行执行。
-
首先构造一个Statementhandler,用来进行后续的参数绑定等相关出来
- 更据ms的类型先够着出对应的statment类型(new SimpleStatementHandler,new PreparedStatementHandler,new CallableStatementHandler)下面以PreparedStatementHandler为丽
- 在statmenthandler中,
RowBounds rowBounds;
,protected BoundSql boundSql;
如果boundSql==null,会生产一个key 和boundSql 不知道干嘛的 - 同时生产对应的parameterhandler处理器和resultSetHandler处理
- 返回一个DefaultParameterhandler处理,同时将插件进行一边处理
- 返回一个DefaultResultSetHandler,同样进行插件处理
- 最后返回对应的stamenthandler,同时进行插件的处理
-
然后进行参数的绑定 即Parameterhandler的处理过程
-
对paramterMapping进行遍历
- 是否又属性名对应的AdditionalParameter
- 如果参数对象为空则直接返回null;
- 查询对应的typehandler处理 由的花则参数值就是parameterOnject
- 利用typehandler进行赋值
-
然后进行执行
有一个KeyGenerator的相关处理 更据自己的设置,是否设置了主键回显
-
-
返回参数,主要是select语句利用 DefaultResultSetHandler 进行处理
3. mybatis中TypeHandler的选取逻辑
注册逻辑:
最终是这种形式 Map<Type, Map<JdbcType, TypeHandler<?>>> typeHandlerMap :其中JDBC可以为null
选取逻辑:
在没有明显的指定的情况下,默认会给一个叫unknownTypehandler的处理器。然后会更具情况来选取
4. myabtis中的一些设计模式
Myabtis中执行器的设计
- myabtis中有
5. mybatis插件的应用时机
一共有四个地方
- 生成executor的时候
- 生产paramhandler的时候
- 生产resulthandler的时候
- 生产statement的时候
6. mybatis的共享程度
7. mybatis的缓存机制
- 没什么用,个人认为就不应该去了解细节,但是可以了解一下学习的方式 分为执行器缓存和configuration
8. mybatis的事务管理
没什么用,到spring中去看
9. 有意思的类
MetaClass:
对一个类的原始信息进行解析,不包含数据。由Reflector类进行支持
Reflector类。对一个类的全面解析。
10 重要的类
public class DefaultSqlSession{
// 选择语句
private <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
// 最终返回的语句
public int update(String statement, Object parameter)
}