前面了解了 MybatisPlus 的初始化流程,指路 MybatisPlus 原理学习:springboot 中 mybatisplus 初始化流程
那现在就来学习一下 MybatisPlus 是怎么执行查询的。这里以 selectPage 为例(不然就得把标题改成 mybaits 了)
发现图片有点大, 所以先简述一下吧,大概执行链路如下:
UserMapper
: 用户定义的 Mapper 接口,继承下 BaseMapper, 执行 selectPageMybatisMapperProxy
:mapper 接口的代理类,创建并缓存每个方法的 mapperMethod 对象,并调用其 execute 方法实现 mapper 方法MybatisMapperMethod
:mapper方法对象,维护对应 mapper 方法的信息(sql 信息,方法参数返回等签名信息),根据 sql 类型调用 sqlSession 不同的方法。 (MP 在这里加了一点分页的处理逻辑,如果返回的是 PageList,则设置 total字段)SqlSessionTemplate
:线程安全的、spring 管理的、支持事务的sqlSession,使用 SqlSessionInterceptor
代理实现 sqlSession 接口,内部通过 SqlSessionFactory
创建 sqlSession 对象,并使用 TransactionSynchronizationManager
(spring 的事务同步管理器)维护,并最终调用 sqlSession 对应接口。DefaultSqlSessionFactory
: 工厂类,openSession
开启一个新的 sqlSession,同时调用 Configuration 创建 executor 用于执行 sql,并使用注册的拦截器生成 executor 的代理链。DefaultSqlSession
:sql 会话,selectList
先获取一下对应mapper 方法的 mapperStatement(对应 xml 的一个 sql 声明),然后使用 executor 执行该 statementMybatisPlusInterceptor
: MP 对应 mybatis 接口的具体拦截器,内部调用自己的 InnerInterceptor 拦截控制执行流程PaginationInnerInterceptor
:MP 的分页拦截插件,需自行配置开启,分页查询时 willDoQuery
中会先生成 count 语句查询 total,total <= 0 就不继续执行了。MybatisCachingExecutor
: executor 装饰者 实现 mybaits 二级缓存,mapper 级别,需手动配置开启MybatisSimpleExecutor
: sql 执行器,使用内部变量localCache
默认实现了 sqlSession 级别的一级缓存。执行 sql 时,使用 statementHandler
生成 sql statement,以及设置参数、执行、处理返回等。PreparedStatementHandler
:处理 statement 的,使用 statement 操作查询数据库,并使用 ResultSetHandler
处理返回结果。(另 insert 时回填自增主键这里也有体现:keyGenerator.processAfter
)PreparedStatement
: java.sql 的 statement,用来执行数据库操作DefaultResultSetHandler
: 数据库结果处理器,将返回的 resultSet 处理成需要的对象,内部实现了自动映射的逻辑,所以一般不用自己配 ResultMap。注:大部分逻辑和 Mybatis 一样的,只是有一部分被 mybatisplus 改写了一些逻辑,(名字 Mybtis 开头的都是改写的)。
emmm,好像也不简。。。 就这样了