[Mybatis源码篇]五、Mybatis执行一条sql的全过程

首先是环境准备,SqlSessionFactory初始化时会解析xml配置文件,解析为Environment、Configuration对象

 通过SqlSessionFactory获取一个SqlSession

 SqlSession中包含一个执行器Executor以及配置类实例:Configuration对象,主要用于sql的执行,是mybatis的核心组件。

 随后通过SqlSession我们可以拿到Mapper的代理对象,代理对象在创建过程中需要我们定义的mapper接口

 通过代理工厂完成代理类的实例化。

 因为是在接口的基础上生成代理对象的,所以直接用了jdk代理。

获取到代理对象后,就可以传入参数执行sql了。

 随后进入代理对象的invoke方法,在代理对象中过滤了Object中的方法(并不是所有方法都需要代理)。

通过MapperMethod执行sql

 上图可以看出mybatis对MapperMethod做了一个缓存,缓存的数据结构为map,key值为mapper方法的全路径。

MapperMethod其实可以看成是一个sql骨架,我们只需要给他填充基本的参数,就可以执行对应的sql。

从缓存中取出MapperMethod后,开始执行sql

 执行时会根据sql的类型做一个区分

 根据返回值的多少,做区分处理,比如我当前执行的查询语句返回值是一个Role对象,那么最终会调用sqlSession的selectOne

 注意,此时参数已经被处理过了

 即使是selectOne,mybatis也会交给selectList处理,但如果返回值不是一个或者0个时,会抛出对应的异常。这个异常并非jdbc抛出,而是mybatis自己抛出。

 通过statement拿到关键的MappedStatement。

这里有两个比较关键的地方。

1、statement是什么?

针对我此时执行的sql,statement是“customer.mapper.RoleMapper.getRole“

其实就是mapper接口中getRole方法的全路径。

这个全路径是不带参数的,作为map的key值,所以在写mapper接口时,不支持重载。

2、MappedStatement是什么?

这个之前的博客已经研究过了,比如说现在用的是xml,MappedStatement就是对xml的一个抽象,比如有参数映射、结果集映射、主键生成规则等

回到主线

调用executor的query方法执行最后的sql查询

 创建一个BoundSql对象

 此时的sql还未替换参数

 最后开始从数据库中查询数据,这里对查询结果也做了一个缓存,也就是说在参数相同时,连续的查询可能不会每次都去数据库查。

 继续向后走,跳过两个步骤后到如下方法

此时已经拿到了Connection对象,并且开始参数赋值了。

以前用原生jdbc时,对预编译的sql设置参数时,通常会用到setInt,setString之类的函数。

mybatis在设置参数时会调用对应的映射器,将Java中的type转变为sql中的type

拿到了最终要执行的sql

 这里的preparedStatement是已经赋值成功后的preparedStatement

执行后结果交给ResultSetHandler来处理,其实就是将结果集解析式对应的Java对象的过程。

 最后跳转到我们自己的程序,拿到最终的结果。

如有错误,欢迎批准指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值