转载

MyBatis源码分析篇---session.selectOne(statement,param)的源码实现

我们已经分析过了会话工厂类实例 SqlSessionFactory ,以及初始化配置文件加载的源码;没看过的童鞋,可以点下面传送门查看:

SqlSessionFactory会话工厂

初始化文件加载分析

这一篇我们来分析一下 SQL 执行流程。

1、创建会话&操作数据库

MyBatis源码分析篇---session.selectOne(statement,param)的源码实现
  • 通过 sqlMapper.openSession() 获取一个可操作数据的“工具” SqlSession ,其中 sqlMapper 则指的是会话工厂 SqlSessionFactory

1.1、 session.selectOne(statement,param)

接下来,我们调用 session.selectOne 方法,由此我们开始源码旅途;

方法全路径: org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)

MyBatis源码分析篇---session.selectOne(statement,param)的源码实现
MyBatis源码分析篇---session.selectOne(statement,param)的源码实现
  • 由上图,我们可以看到,首先是根据 statementId 获取到一个 MappedStatement ,看过初始化篇的童鞋,应该一下就能反应过来,这个 MappedStatement 是在初始化解析的过程中初始化保存的,该对象中包含了 SQL 执行需要的所有信息:
MyBatis源码分析篇---session.selectOne(statement,param)的源码实现
  • 获取到 MappedStatement 之后,调用执行器执行 SQL ;
  • 这里我们可以直接执行源码包下的测试方法 org.apache.ibatis.session.SqlSessionTest#shouldSelectOneAuthor ,如下图:
MyBatis源码分析篇---session.selectOne(statement,param)的源码实现
  • 需要说明的是:执行器 Excutor 使用的是责任链模式,(设计模式相关的信息会在后面的博文中详细说明)

1.2、 CachingExecutor#query

  • 通过上图我们可以直观的看出,这里调用执行器执行 SQL 的时候,首先调用的是缓存执行器中的 query 方法;

  • 方法全路径: org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)

MyBatis源码分析篇---session.selectOne(statement,param)的源码实现
  • CachingExecutor#query 方法之后调用的是 BaseExcutor#query 方法,之后的调用过程,可参考下图
MyBatis源码分析篇---session.selectOne(statement,param)的源码实现
  • BaseEexcutor 处理一级缓存,获取 BoundSql 等操作;
  • SimpleExecutor 获取到 Configuration ,创建 StatementHandlerParameterHandlerResultHandler ;创建 Connection ,调用 handler.parameterize(stmt) 处理参数;
  • PreparedStatementHandler 预编译 SQL ,调用 ps.execute(); 执行 SQL
  • DefaultResultSetHandler 处理结果集,最终返回数据。

结语

  • 至此我们就完成了 SqlSessionFactory 的创建, SqlSession 的获取,以及 session.selectOne(statement,param) 的全部执行流程。

  • 下篇我们将着重分享一下我们经常使用的方式操作数据库 org.apache.ibatis.session.SqlSession#getMapper

  • 下属方法疏通同归,我们就不一一分享了;

  • org.apache.ibatis.session.SqlSession#selectOne(java.lang.String)
    org.apache.ibatis.session.SqlSession#selectOne(java.lang.String, java.lang.Object)
    org.apache.ibatis.session.SqlSession#selectList(java.lang.String)
    org.apache.ibatis.session.SqlSession#selectList(java.lang.String, java.lang.Object)
    org.apache.ibatis.session.SqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
        
    //上面的5个方法最终间接或直接的都会调用到,之后的源码执行流程同上图
    org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
    复制代码
  • 如若有遗漏部分,还请指正。

原文  https://juejin.im/post/5ea2e6fcf265da47ef2f467e
正文到此结束
Loading...