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 ...
随机推荐
- Fitting Bayesian Linear Mixed Models for continuous and binary data using Stan: A quick tutorial
I want to give a quick tutorial on fitting Linear Mixed Models (hierarchical models) with a full var ...
- Django框架全面讲解
Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...
- ArcGIS 网络分析[2.5] VRP(车辆配送)
什么是VRP? VRP就是车辆配送. 大家有没有想象过一个城市的某个快递营业点,是怎么让各个快递员配送快递的? 每个快递员针对那片区域的客户,如何走路线才最省时间? 也许你会说,最短路径分析可以做到— ...
- 侯捷STL学习(四)--allocator和容器时间的实现关系
第十一节 分配器 分配器的好坏影响到容器的性能 operator new()里面调用malloc D:\Program Files (x86)\Microsoft Visual Studio 12.0 ...
- nodeJs中npm详解
npm 是 Node.js 的模块依赖管理工具.作为开发者使用的工具,主要解决开发 node.js 时会遇到的问题.如同 RubyGems 对于 Ruby 开发者和 Maven 对于 Java 开发者 ...
- js for循环 等腰三角形demo
<script> for(var i=1;i<10;i++){ for(var j=1;j<10-i;j++){document.write(" ")} f ...
- 什么时候该选用Xamarin?
现在开发app也好,桌面程序也好,有很多不同的技术可以选择.那么,什么时候应该选用Xamarin呢? 5 questions to consider before choosing Xamarin 1 ...
- OSS web直传 ajax方式 上传图片、文件
部分js代码 send_request = function(){//这是从后台获取认证策略等信息. var htmlobj=$.ajax({url:root+"/service/polic ...
- css简单了解
今天主要是说一下css样式表!HTML结合他使用可以是HTML页面变得很绚丽多彩! 先简单介绍一下为什么要使用CSS(Cascading Style Sheets)层叠样式表! 1.因为CSS样式表可 ...
- 非滤波单目视觉slam笔记1
非滤波单目视觉slam 主要分为以下8部分 数据类型 数据关联 初始化 位姿估计 地图维护 地图生成 失效恢复 回环检测 数据类型 直接法(稠密,半稠密) 基本原理是亮度一致性约束,\(J(x,y) ...
