MyBatis系列 (2) ~ 查询执行过程

    本文继续沿用MyBatis系列 (1) ~ 启动的demo,并在上文基础上,说明MyBatis到底是如何执行sql的。MyBatis执行一个查询方法,可以分为两步:Session的创建结果的获取。本文的内容是基于demo特定代码的结果,如果你的配置文件或测试代码不一致,结果可能不一样。

一、Session的创建

    1.如测试代码所示【测试代码和demo详见MyBatis系列 (1) ~ 启动】,调用ssf.openSession方法(图1),将会返回一个session对象。而openSession()调用openSessionFromDataSource方法(图2),在openSessionFromDataSource方法(图3)中configuration.newExecutor会生成一个Executor实例(图4),而这个Executor对象则是一个CachingExecutor实例,包装了SimpleExecutor实例(图5),最后再利用Executor创建DefaultSqlSession实例并返回(图3),至此session创建完成。session对于sql的执行,都是利用executor去完成,可以说Executor是seeeion最重要的对象

MyBatis系列 (2) ~ 查询执行过程_第1张图片
图1 测试代码
MyBatis系列 (2) ~ 查询执行过程_第2张图片
图2 openSession方法
MyBatis系列 (2) ~ 查询执行过程_第3张图片
图3 openSessionFromDataSource方法
MyBatis系列 (2) ~ 查询执行过程_第4张图片
图4 configuration.newExecutor 方法
MyBatis系列 (2) ~ 查询执行过程_第5张图片
图5 CachingExecutor方法

二、结果的获取

    这个过程大概会经过MappedStatement查找、BoundSql的创建、CacheKey的创建、缓存查找、JDBC操作(数据库Connection建立、Statement建立、参数设置、结果处理)、缓存更新这几个步奏。其中缓存的部分以后再分析。

    1.MappedStatement查找。从Configuration对象的mappedStatements根据id获取。mappedStatement如何添加到mappedStatements可以参照MyBatis系列 (1) ~ 启动。

MyBatis系列 (2) ~ 查询执行过程_第6张图片
图6 MappedStatement查找

        2.BoundSql的创建。调用MappedStatement的getBoundSql方法会创建并返回一个BoundSql实例。BoundSql会封装好sql、参数、类型、typeHandler等信息,具体过程如下所示。

MyBatis系列 (2) ~ 查询执行过程_第7张图片
图7 BoundSql的创建

          3.CacheKey的创建。调用CachingExecutor的createCacheKey方法会返回一个CacheKey对象实例。CacheKey根据MappedStatement的id,偏移量,sql,参数,environment的id标识。如果他们都相等,则可以判断CacheKey也相等。ddemo的CacheKey为"-1623403364:769426577:User.selectOneUser:0:2147483647:select t.id,t.name from user t where id = ?:2:development"。

MyBatis系列 (2) ~ 查询执行过程_第8张图片
图8 CacheKey的创建

        4.JDBC操作。数据库连接是在这里这里建立的,并不是一创建一个session实例就会建立一个连接。Connection由dataSource的doGetConnection方法返回。参数是由TypeHandler设置。

图9 JDBC相关操作
MyBatis系列 (2) ~ 查询执行过程_第9张图片
图10 数据库连接
MyBatis系列 (2) ~ 查询执行过程_第10张图片
图 11 Statement
MyBatis系列 (2) ~ 查询执行过程_第11张图片
图12 参数设置
MyBatis系列 (2) ~ 查询执行过程_第12张图片
图13 结果处理

        4.更新缓存。把相关结果存到localCache对象中,对于相同的CacheKey,如果缓存中有值,则不需要到数据库去查询。

MyBatis系列 (2) ~ 查询执行过程_第13张图片
图14 缓存更新

        最后把结果返回给调用者,至此,MyBatis查询执行结束。

你可能感兴趣的:(MyBatis系列 (2) ~ 查询执行过程)