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 ...
 
随机推荐
- java 与操作系统进程同步问题(一)————互斥问题
			
最近学校开设了操作系统原理课程,老师要求用任意语言去模拟进程的同步和互斥问题. 在尝试的写了之后,发现这个问题非常有意思,故想记录在博客中,作为自己的学习轨迹. 个人还是比较喜欢用Java语言,所以采 ...
 - python 基础篇 2
			
三.对变量.对象与赋值的浅析 1.不记住就完蛋了 1.1 记住:一切数据都是对象 1.2 记住:一切变量都是对数据对象的一个引用 1.3 分析:python内部的引用计数 sys.getrefcoun ...
 - VR全景智慧城市-提前进入商家观景,涵盖实体行业
			
互联网发展的迅猛势头,让很多的实体商家翻了个大跟头,更有言说,未来的大街小巷根本见不到逛街的人,可是线上商城相继曝出的假货谁来买单?相比之下眼见为实更让消费者心里觉得踏实.所以,全景智慧城市更能满足大 ...
 - 入职这一段时间的总结,Don't Repeat Yourself.
			
1.第一次接触到大型软件系统的开发,现在我们使用的是 python + flask +vue.js ,数据库:postgresql 2. 不要在自己不懂的情况下复制代码,每次分析一段代码的时候,就跟以 ...
 - scrapy跟pyspider的杂谈
			
最近有一个私人项目要搞,可能最近的博客都会变成爬虫跟数据分析类的了.既然是爬虫,第一反应想到的就是鼎鼎大名的scrapy了,其次想到的pyspider,最后想到的就是自己写. scrapy是封装了tw ...
 - Android布局方式
			
1. LinearLayout(线性布局) android:orientation="vertical" android:layout_width="wra ...
 - 基于angular的route实现单页面cnodejs
			
Angular ui-router 前言 之前不太理解前端怎么实现路由功能,以前知道有一种方式使用html5的pushState可以操作url才实现路由的功能,在实践项目中也用过一次,后来这种操作叫成 ...
 - Qt自定义标签按钮
			
当你接触到Qt时,你会为它极为方便的跨平台方面感到吃惊,从而想尝试着使用Qt.渐渐地你会发现Qt自带的一些控件不能满足自己的需要,此时就需要我们自己定义一个属于自己的控件.总所周知,标签的风格设置类比 ...
 - 再来写一个随机数解决方案,对Random再来一次封装
			
本文提供对Random的封装,简化并扩展了其功能 获取随机数,确保同时调用不会重复 //new Random().Next(5); RandomTask.Next(); 从一个列表中,随机获取其中某个 ...
 - 关于javascript闭包理解
			
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一:关于变量的作用域 Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. ...
 
			
		