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 ...
随机推荐
- 使用sqlserver搭建高可用双机热备的Quartz集群部署【附源码】
一般拿Timer和Quartz相比较的,简直就是对Quartz的侮辱,两者的功能根本就不在一个层级上,如本篇介绍的Quartz强大的序列化机制,可以序列到 sqlserver,mysql,当然还可以在 ...
- 简单VR照片 使用陀螺仪、姿态角(Roll、Pitch、Yaw )、四元数
最近在做一个类似VR照片的demo,跟全景图片也很像,只是VR照片与全景720度显示,我只做了180度.但我发现他们实现的原理有一丝相似,希望可以给一些想入行AR.VR的朋友一些提示吧. ...
- 学习笔记TF020:序列标注、手写小写字母OCR数据集、双向RNN
序列标注(sequence labelling),输入序列每一帧预测一个类别.OCR(Optical Character Recognition 光学字符识别). MIT口语系统研究组Rob Kass ...
- SQLalchemy模块用法
安装 pip install sqlalchemy #!/usr/bin/env python # -*- coding:utf-8 -*- # 加载模块 from sqlalchemy.ext.de ...
- 【Web开发】Mean web开发 01-Express实现MVC模式开发
简介 Mean是JavaScript的全栈开发框架.更多介绍 用Express实现MVC模式开发是Mean Web全栈开发中的一部分. Express 是一个基于 Node.js 平台的极简.灵活的 ...
- Android上解析Json格式数据
package com.practice.json; import org.json.JSONArray; import org.json.JSONException; import org.json ...
- javaCV开发详解之4:转流器实现(也可作为本地收流器、推流器,新增添加图片及文字水印,视频图像帧保存),实现rtsp/rtmp/本地文件转发到rtmp流媒体服务器(基于javaCV-FFMPEG)
javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...
- Canvas学习系列一:初识canvas
最近你开始在学习canvas,打算把学习canvas的整个学习过程当中的一些笔记与总结记录下来,如有什么不足之处还请大神们多多指出. 1. 认识canvas Canvas元素的出现,可以说开启的Web ...
- chip-seq数据分析中peak-calling软件-------MACS的安装
1.下载MACS软件安装包(作者的系统为Ubuntu) 网址链接:http://liulab.dfci.harvard.edu/MACS/ 2.解压文件: tar -zxvf MACS**.tar.g ...
- tomcat之 Tomcat 7.0.78 单机多实例配置
前言:JDK(JavaDevelopment Kit)是Sun Microsystems针对Java开发员的产品.自从Java推出以来,JDK已经成为使用最广泛的javaSDK. JDK是整个Java ...