mybatis 09 总结

  1. UserMapper
  2. SqlSession
  3. Executor
  4. 循环依赖&延迟加载
  5. 一级缓存
  6. 二级缓存
  7. StatementHandler
  8. 结果集处理器(划重点)
  9. xml解析
  10. Configuration

UserMapper

当你编写了一个UserMapper,项目运行后,mybatis 会对这个类做动态代理(MapperProxy),底层基于java proxy。

SqlSession

sqlsession。会话。门面模式,对于开发者来说,调用起来相当方便。

要注意,这里面有些select方法是没有返回值的,那查询的机制怎么实现?是通过开发者传入自定义ResultHandler来处理结果集。

Executor

执行器。mybatis的核心,主要两个功能,update和query。其他共性:缓存、事务、批处理、提交。Executor里面有个deferLoad,这个是用来做延迟加载的,避免循环依赖(博客和评论)。

MappedStatement是一个映射信息的包装对象,里面携带了完整的sql动作声明

BatchExecutor。只有增删改可以批处理。批处理下,什么会被视为同一个statement呢?相同sql+连续

BatchExecutor最后要调用flushStatements,才能提交数据

循环依赖&延迟加载

deferLoad延迟加载不是懒加载,依赖一级缓存。它会设置一个占位符,当用到的时候,才去设置值(对象被MyBatis动态代理了)

子查询都是手动映射的,DefaultResultSetHandler.applyPropertyMappings

循环依赖解决方案,核心类DefaultResultSetHandler,入口方法getNestedQueryMappingValue,流程:

  • 创建CacheKey
  • 是否命中一级缓存
  • 命中一级缓存的情况下,canLoad是否可直接加载?缓存是否有值,且不是占位符EXECUTION_PLACEHOLDER
  • 循环加载过程中,queryStack递增,不停设置延迟加载的占位符。循环结束,此时所有值都到达一级缓存。这时,MyBatis将所有占位符换成一级缓存中的内容。

一级缓存

请求进来,二级缓存在前,一级缓存在后

一级缓存很简单,是个哈希map,设计上不考虑内存溢出的问题,因为一级缓存的生命周期基于sqlsession会话,若出现内存溢出,那是业务代码设计有问题

二级缓存

二级缓存是一个完整的缓存解决方案,内部装饰(delegate)了一级缓存

二级缓存默认使用了内存存储,内部使用linkhashmap。链表本身机制非常适合增(改)和删,只要在链表中加一个节点即可

mybatis框架里,二级缓存设计的很经典,应用了责任链模式、装饰者模式

二级缓存体系下,数据需要在提交之后才会命中缓存(怕脏读等问题)注意:ScheduleCache会做监控,超过一定时间后,清空整个二级缓存

transactionalCacheManager(事务缓存管理器),生命周期与会话同步。里面有成员变量,map用于管理N个transactionalCache(暂存区)

查询的时候,先查暂存区,暂存区去缓存区里查询

StatementHandler

StatementHandler。一次会话中有一个执行器,对应一个或多个StatementHandler。

StatementHandler有三种实现,通常我们都用PrepareStatementHandler,它是预处理的。

一句话总结:StatementHandler就是处理jdbc相关操作,内部:

  • 创建JDBC
  • 创建sql、设置参数,由ParameterHandler完成
  • 执行sql
  • 读取结果,由ResultSetHandler完成

结果集处理器(划重点)

解决java bean与数据库表格行的映射关系

MetaObject是元对象,映射了java bean,mybatis reflection 这个包下面的工具类都很强大

ResultMap是查询结果对象

ResultMapping,声明映射关系,最终会体现到ResultMap

联合查询&嵌套映射:

  • 一对一,查询两个,然后映射
  • 一对多,去看关键方法handleRowValuesForNestedResultMap:
    假设查询结果是1:3。那么数据库层面看查询结果应该是三条数据
    首先,程序会根据用户定义的id生成rowkey对象,然后得到(从联合嵌套暂存区中拿,没有的话实例化出来)当前查询结果ResultMapping,接着开始填充复合属性(开始递归)
  • 在上面的递归过程中,每得到一个映射java bean对象,都会被放入特定的暂存区中,key是rowkey。

xml解析

xml解析环节,节点对象设计采用了命令模式,语法采用ognl表达式,内部逐层递归解析

Configuration

1、加载用户的所有配置:

  • mybatis conf.xml
  • mapper.xml
  • mybatis annotation

2、全局组件加载

3、应用简单工厂,标准化创建、统一包装Executor


转载请注明来源。 欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。 可以在下面评论区评论,也可以邮件至 sharlot2050@foxmail.com。

文章标题:mybatis 09 总结

字数:1.1k

本文作者:夏来风

发布时间:2020-07-04, 20:00:24

原始链接:http://www.demo1024.com/blog/mybatis-09-end/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。