MyBatis源码解析【6】SqlSession运行
前言
这个分类比较连续,如果这里看不懂,或者第一次看,请回顾之前的博客
http://www.cnblogs.com/linkstar/category/1027239.html
经过之前的学习我们知道了工厂是如何建立的,是如何生产产品的。
那么今天要进入重点中的重点了。那就是我们究竟是如何使用这个产品的。
也就是SqlSeesion究竟是如何运行的,内部究竟有些什么东西。
这部分很难,需要使用到我们之前的基础装备哦。
产品运行的大致步骤
我们还是老规矩从外部来看看是如何运行的。
SqlSession session = sqlSessionFactory.openSession();Demo demo = (Demo) session.selectOne("com.xex.dao.mapper.DemoMapper.selectDemo");session.close();从外部看,最简单的情况就是这样,看起来比较简单。1、从工厂获取产品(获取产品已经在上节提到,这里就不多说了)2、执行需要的sql方法(重点)3、关闭产品(回收产品)
产品运行的内部过程
从大致的步骤我们可以看出重点就在第二步上面了。怎么随便调用一个方法就能执行sql了呢?过程复杂,我尽量讲的仔细一些。我们就以这个查询来作为例子。 首先我们进入selectOne方法里面看看。(idea使用快捷键Ctrl+Alt+B查看光标上的方法的实现)
我们需要查看的是DefaultSqlSession的实现,至于为什么之前已经讲过咯。

留意一个地方,我们传入的参数statement="com.xex.dao.mapper.DemoMapper.selectDemo"

从大方向上看,传入的参数是“com.xex.dao.mapper.DemoMapper.selectDemo”,返回的参数是一个类MappedStatement

mappedStatements简述
这里用文字来叙述一下这个mappedStatements的构建思路。因为具体细节太多,就不一一截图说明了,就截图重点部分了,希望你能跟上并按照思路去源码中寻找。
但是这个类里面一些细节值得我们学习和研究,所以很值得看看。
1、首先这mappedStatements是我们熟悉的Configuration类中的一个变量。
2、是这样被new出来的:new StrictMap
3、StrictMap是Configuration中的一个内部类继承自HashMap,与之不同的是的,这个map有个名字name的变量,然后主要不同在于这个map的put和get方法。
4、put方法中:

下面有这么几句话是用来描述这个put方法的,看完之后仔细思考,这三条是怎么总结出来的。
一、这个map会把com.xex.dao.mapper.DemoMapper.selectDemo这种包名按照“.”拆分后取出最后一个元素,这里就是selectDemo。(只是举例)
二、这个map的值都是String,如果在put的时候发现有相同的key,那么不会马上抛出异常,而是覆盖了重复的键,把重复键的值修改成了Ambiguity类型。
三、Ambiguity这个类其实就是一个字符串。
首先对于第一条,因为拆分之后最后的selectDemo是我们写的一条条sql语句的id,mybatis是通过这个id去寻找需要运行那一条数据库语句的,所以这个必须唯一。而存放的时候只需要最后的selectDemo就可以了。
那么就奇怪了,为什么mybatis遇到相同的键也就是有两条sql语句有相同的id时没有直接选择在加载配置的时候就抛出异常而是存放了一个奇怪的Ambiguity类型呢?(Ambiguity的意思是含糊的,不明确的)
让我们来看看get方法应该就明白了。

一、调用父类的get也就是HashMap的get方法。
二、空值抛异常
三、Ambiguity抛异常
聪明的你应该已经明白了。
给笨笨的你解释一下,空值抛异常就是通过这个id找不到对应的需要执行的sql语句当然就异常了;当Ambiguity抛异常就表面有两个id相同的sql语句,mybatis不知道要执行哪一个了,所以异常了。
剩下的就是这个map是什么时候建立的呢?当然是一开始建造工厂的时候咯,之前有讲过,不明白可以翻翻前面的,复习一下咯。
具体在MappedStatement里面sql是怎么存放的,有兴趣的可以直接进这个类看看。这里我们就讲到这里了,要继续主进程了。
sql的执行
我们继续来接着之前的来看,获得了sql之后怎么执行的呢?
return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
首先是谁去执行的?一个叫做executor的东西。
我们叫它执行者。它是一个接口。然后在产品生产的时候就被赋值了。
然后是它去执行的query方法,返回值是一个泛型约束的List。
然后我们来看参数:
1、ms是我们刚才获得的执行语句。
2、wrapCollection是将当前的参数,也就是数据库查询的时候的入参,比如查询条件,如果查询条件是集合(Collection)或者数组(Array)形式的话转换成map,如果不是就直接返回。
我们现在没有入参,所以返回的是个null
3、rowBounds mybatis的分页功能,我们不管他
4、Executor.NO_RESULT_HANDLER
是个null,叫做没有结果的处理器
然后我们来看看执行


下面就是关键了!!!注意咯

从缓存中拿我们就不看了,比较简单,缓存其实是个map嘛
我们就看从数据库查询


下面走这个


看到这里的excute没有,这里就是真正的执行sql了,里面呢就是传说中的jdbc了,喜欢你就进去看看,不喜欢我们继续看看结果集最后是如何映射的。
对返回结果的处理

至此整个sql在mybatis中的执行过程终于是完成了。
整条路线如果仔细来看真的很长,不得不佩服设计者如此缜密的设计。
总结
我们经过整个路线的行走,我们已经明确了sql在mybatis中执行的全部过程。
相信你也有所收获,其实我们应该多想想设计者为何这样设计,有的代码为什么要这样写。这样写的好处和设计思路又是什么。有什么样的优化或者优点值得我们学习。
不过不要高兴的太早。
这还没完呢!
我们的装备到现在还没用上呢!后面一篇就会讲解,为什么只需要定义一个接口在mybatis中就能起作用,不需要实现类。
代理模式在其中的运用以及反射的强大。
希望上面的思路对你看源码有帮助。如有问题还请多多提出,不胜感激。
转载请注明出处:http://www.cnblogs.com/linkstar/category/1027239.html
作者:LinkinStar
MyBatis源码解析【6】SqlSession运行的更多相关文章
- Mybatis源码解析(四) —— SqlSession是如何实现数据库操作的?
Mybatis源码解析(四) -- SqlSession是如何实现数据库操作的? 如果拿一次数据库请求操作做比喻,那么前面3篇文章就是在做请求准备,真正执行操作的是本篇文章要讲述的内容.正如标题一 ...
- Mybatis源码解析4——SqlSession
上一篇文章中,我们介绍了 SqlSessionFactory 的创建过程,忘记了的,可以回顾一下,或者看下下面这张图也行. 接下来,可乐讲给大家介绍 Mybatis 中另一个重量级嘉宾--SqlSes ...
- 【MyBatis源码解析】MyBatis一二级缓存
MyBatis缓存 我们知道,频繁的数据库操作是非常耗费性能的(主要是因为对于DB而言,数据是持久化在磁盘中的,因此查询操作需要通过IO,IO操作速度相比内存操作速度慢了好几个量级),尤其是对于一些相 ...
- mybatis源码-解析配置文件(三)之配置文件Configuration解析
目录 1. 简介 1.1 系列内容 1.2 适合对象 1.3 本文内容 2. 配置文件 2.1 mysql.properties 2.2 mybatis-config.xml 3. Configura ...
- Mybatis源码解析,一步一步从浅入深(一):创建准备工程
Spring SpringMVC Mybatis(简称ssm)是一个很流行的java web框架,而Mybatis作为ORM 持久层框架,因其灵活简单,深受青睐.而且现在的招聘职位中都要求应试者熟悉M ...
- Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码
在文章:Mybatis源码解析,一步一步从浅入深(一):创建准备工程,中我们为了解析mybatis源码创建了一个mybatis的简单工程(源码已上传github,链接在文章末尾),并实现了一个查询功能 ...
- Mybatis源码解析(一) —— mybatis与Spring是如何整合的?
Mybatis源码解析(一) -- mybatis与Spring是如何整合的? 从大学开始接触mybatis到现在差不多快3年了吧,最近寻思着使用3年了,我却还不清楚其内部实现细节,比如: 它是如 ...
- Mybatis源码解析,一步一步从浅入深(四):将configuration.xml的解析到Configuration对象实例
在Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们看到了XMLConfigBuilder(xml配置解析器)的实例化.而且这个实例化过程在文章:Mybatis源码解析,一步一步从浅 ...
- Mybatis源码解析,一步一步从浅入深(六):映射代理类的获取
在文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们提到了两个问题: 1,为什么在以前的代码流程中从来没有addMapper,而这里却有getMapper? 2,UserDao ...
- Mybatis源码解析,一步一步从浅入深(七):执行查询
一,前言 我们在文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码的最后一步说到执行查询的关键代码: result = sqlSession.selectOne(command.ge ...
随机推荐
- Sampling Distributions and Central Limit Theorem in R(转)
The Central Limit Theorem (CLT), and the concept of the sampling distribution, are critical for unde ...
- 常见的几种Flume日志收集场景实战
这里主要介绍几种常见的日志的source来源,包括监控文件型,监控文件内容增量,TCP和HTTP. Spool类型 用于监控指定目录内数据变更,若有新文件,则将新文件内数据读取上传 在教你一步搭建Fl ...
- mongoDB数据库的简单使用
我的第一篇小文章,以前总是写Evernote. mongodb属于非关系型数据库中的文档型数据库. 1.下载安装mongoDB, 文件自动 存放在这个目录下:C:\Program Files\Mong ...
- 基于FPGA的均值滤波算法的实现
前面实现了基于FPGA的彩色图像转灰度处理,减小了图像的体积,但是其中还是存在许多噪声,会影响图像的边缘检测,所以这一篇就要消除这些噪声,基于灰度图像进行图像的滤波处理,为图像的边缘检测做好夯实基础. ...
- oracle 11g 完全卸载方法
网上好多卸载教程都前篇一律,但很多卸完重装都有问题,卸了几次装了几次,就特地总结整理一下 另外说一句:在完全删除(或者叫卸载)oracle时,没有必要特别意oracle提示问题,只要把oracle痕迹 ...
- CSS实现文字和图片的水平垂直居中
关于文字和图片的水平垂直居中,在前端界绝对算是一个老生常谈的问题了,尤其是垂直居中,什么千奇百怪的解法都能想的出来.下面我就总结一些比较常用的方法: 一.文本的水平垂直居中: 1.水平居中: 是不是很 ...
- 水平方向的RecyclerView
最近做了一个项目需要实现一个卡片式的水平滑动,但是不能手势滑动,点击卡片上的按钮之后滑动到下一个卡片,所以想到用RecyclerView实现,去掉它的手势滑动,点击按钮之后再代码控制滑动到下一个卡片. ...
- 《学习OpenCV3》第7章第4题-SVD奇异值分解的验算
原文题目: 中文翻译: 解题过程 d.使用OpenCV编写代码 , , , , ,); Mat A = static_cast< ...
- CoreLocation 框架
获取设备的地理位置和方向 一.概述 CoreLocation框架,它提供了如下几种服务 确定设备的地理位置 高度 方向 或到附近 iBeacon 的相对位置. 这个框架使用所有可用的车载硬件.如 Wi ...
- AngularJS高级程序设计读书笔记 -- 服务篇
服务是提供在整个应用程序中所使用的任何功能的单例对象. 单例 : 只用一个对象实例会被 AngularJS 创建出来, 并被程序需要服务的各个不同部分所共享. 1. 内置服务 一些关键方法也被 Ang ...
