Mybatis:体系结构和工作原理

主要流程

  • 解析配置文件
  • 创建工厂类
  • 创建会话
  • 会话操作数据库

架构分层

SqlSession

如果代码在事务里,一次请求的SqlSession一样,否则每次都会创建一个SqlSession。

缓存

一级缓存(默认开启):作用域:SqlSession级别。存放在SqlSession中的Excutor里。在执行增、删、改操作以后,缓存会删除。
二级缓存(需要在xml手动开启):作用域:namesapce(也就是同一个mapper),二级缓存优于一级缓存。(通过装饰器模式实现)
二级缓存跨mapper:可以使用Cache ref,让ClassMapper引用StudenMapper命名空间,这样两个映射文件对应的SQL操作都使用的是同一块缓存了
缓存的key:mapper+方法名+参数信息+翻页信息
还可以指定某些方法不使用二级缓存。

源码分析

配置文件解析

创建解析器->
解析xml->

  • 插件会解析到拦截器链里
  • 解析事务管理器
  • 解析增删改查标签->产生MappedStatement
  • bindType -> 存在了 <接口类型、代理工厂类>的map中
    最后返回一个Configuration对象,build(config)以后返回SqlSessionFactory对象
SqlSessionFactory

实现类是DefaultSqlSessionFactory
openSession:创建事务、创建执行器(BATCH、REUSER、SIMPLE默认)、二级缓存包装执行器、加载插件、返回DefaultSqlSession

SqlSession

sqlsession.getMapper(xxxMapper.class)。
为何获取mapper,通过mapper解耦,保证代码的鲁棒性。
之前有将bindType将 <接口类型、代理工厂类>放在map里,这里去拿出来,通过工厂类newInstance方法创建新的代理mapper对象。

为何mybatis动态代理不需要实现类

只需要将mapper.方法 和xml中的namespace.sqlId映射起来即可。不需要基础实现,所以没有实现类。
绑定是通过接口+方法名

查询流程

代理对象invoke方法,调用MapperMethod.excute(sqlSession),发现是调用sqlSession的select方法,这个方式是通过Configuration找到MappedStatement,然后用内部的Executor来获取连接执行这个MappedStatement,执行过程中会创建三大天王:StatementHandler、ParameterHandler、ResultSetHandler,进行参数上的处理、结果集的处理、预编译sql等等。
配置文件只初始化一次,SqlSessionFactory -> SqlSession -> Executor -> StatementHandler默认PREPARE(预编译) (parameterHandler处理参数)-> 执行查询 -> 处理结果(ResultSetHandler)

可以被插件的4大天王

Executor、StatementHandler、ParameterHandler、ResultSetHandler

原文地址:https://www.cnblogs.com/fcb-it/p/13269764.html