mybatis框架在操作数据的时候,离不开SqlSession接口实例类的作用。可以说SqlSession接口实例是开发过程中打交道最多的一个类。即是DefaultSqlSession类。如果笔者记得没有错的话,早期是没有什么getMapper方法的。增删改查各志有对应的方法进行操作。虽然现在改进了很多,但是也保留了很多。我们依旧可以看到类似于selectList这样子的方法。源码的例子里面就可以找到。如下

    SqlSession session = sqlMapper.openSession(TransactionIsolationLevel.SERIALIZABLE);try {List<Author> authors = session.selectList("org.apache.ibatis.domain.blog.mappers.AuthorMapper.selectAllAuthors");assertEquals(2, authors.size());} finally {session.close();

当然从某种意义上来讲,写起有一点烦。但是不可否认他的功能的确存在。这也是笔者为什么比较喜欢用动态代理来进行数据上的操作。至少可观性上笔者认为比较好吧。

不管是哪一种数据上的操作都离不开SqlSession接口实例。所以深入查看qlSession接口实例就显得相当的重要。笔者选择了DefaultSqlSession类的selectList方法作为入口点进行切入。代码如下。

 1  public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {2     try {3       MappedStatement ms = configuration.getMappedStatement(statement);4       return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);5     } catch (Exception e) {6       throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);7     } finally {8       ErrorContext.instance().reset();9     }
10   }

源码的意思是从configuration变理里面获得,在通过Executor类的query方法获得相应的结果。让我们想想上一章中讲过MappedStatement类是用于存放select节点或是update节点的信息。也就是说这里传入statement参数表示将要去执行哪一个select节点。传入的参数自然就是select节点id对应的值。那么Executor类又是什么。如果比较认真的人来查看源码的话,你会发现基本上都会用到Executor类实例。在一次叹气——架构之美。

DefaultSqlSession类的成员executor是在构造函数里面给他赋值的。所以我们又要回头去查看一下是在什么时候实例化了DefaultSqlSession类。笔者在第一章结尾的时候也讲到过关于Executor类。从源码中我们可以看到他是通过Configuration类的newExecutor方法来得到的。代码如下

 1 public Executor newExecutor(Transaction transaction, ExecutorType executorType) {2     executorType = executorType == null ? defaultExecutorType : executorType;3     executorType = executorType == null ? ExecutorType.SIMPLE : executorType;4     Executor executor;5     if (ExecutorType.BATCH == executorType) {6       executor = new BatchExecutor(this, transaction);7     } else if (ExecutorType.REUSE == executorType) {8       executor = new ReuseExecutor(this, transaction);9     } else {
10       executor = new SimpleExecutor(this, transaction);
11     }
12     if (cacheEnabled) {
13       executor = new CachingExecutor(executor);
14     }
15     executor = (Executor) interceptorChain.pluginAll(executor);
16     return executor;
17   }

完了。没有想到Executor类还有分种类的。说实话笔者若是没有去查看源码真不会知道原来Executor类还有分种类的。看上面的源码笔者刚开始认为有四种。但是发现最后一个跟上面的三个实例上有一点不同。为了更进一步确认笔者不得不去查看一下官网上面的API。笔者把内容复制过来。如下。

ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情。它为每个语句的执行创建一个新的预处理语句。
ExecutorType.REUSE: 这个执行器类型会复用预处理语句。
ExecutorType.BATCH: 这个执行器会批量执行所有更新语句,如果 SELECT 在它们中间执行还会标定它们是 必须的,来保证一个简单并易于理解的行为。

看样子官网解释的很清楚了。笔者就不在这里多言了。那么默认情况下mybatis框架又是调用哪一个Executor子类呢?其实这一点是可以在源码上找到的。如下

Configuration类:

protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;

相信大家都明白了如果都没有指定相应的Executor类的类型的话,mybatis框架会去调用SimpleExecutor类。

对于Executor类我先了解到这里。因为后面大量要用到他,同时也只有结合后面的功能才明白Executor类的作用。从上面DefaultSqlSession类的selectList方法中我们可以发现最后会去调用Executor类的query方法。

return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);

对于变量ms笔者就不多说了。wrapCollection方法却是值得注意的。他意思是先判断变理parameter是否是Collection类型,如果是,就是新建一个StrictMap类型并以“collection”为key进行存放。又查一下是不是List类型。如果是,就以“list”为key进行存放。接下就是判断是不是数组类型,如果是,就是新建一个StrictMap类型并以“array”为key进行存放。最后返回回StrictMap类实例。当然如果上面都不是的话,就直接返回parameter了。如果不清楚为什么设计者要这样子做不要紧,笔者这个时候也不知道为什么。所以笔者只要记得他做了什么。RowBounds类型变理rowBounds一般用于分页。默认是0到2147483647值,相信这个够你用了吧。ResultHandler是用于处理返回的结果,这里直接就不要处理返回的结果了。所以笔者就不用讲了。

BaseExecutor类:

  public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {BoundSql boundSql = ms.getBoundSql(parameter);CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);return query(ms, parameter, rowBounds, resultHandler, key, boundSql);}

类似于SimpleExecutor这样子类并不是直接的继承了Executor类。而是通过BaseExecutor类这一层之后到继承Executor类。所以query方法调用的时候并不是调用SimpleExecutor类的。而是调用BaseExecutor类的。当然你从SimpleExecutor类也找不到query方法。显然是经过BaseExecutor类进行处理相关的信息之后,在去调用Executor子类的doQuery方法。所以我们可以找到SimpleExecutor类的doQuery方法。这个过程笔者就不想细说。笔者主要目地还是引导大家去看的。

SimpleExecutor类:

 1  public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {2     Statement stmt = null;3     try {4       Configuration configuration = ms.getConfiguration();5       StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);6       stmt = prepareStatement(handler, ms.getStatementLog());7       return handler.<E>query(stmt, resultHandler) ; 8     } finally {9       closeStatement(stmt);
10     }
11   }

从源码上来看笔者只认识俩个类一个是Configuration类和Statement类。Statement类是属于JDBC的知识点。Configuration类是属于mybatis框架的配置信息部分。意思就是通过MappedStatement获得Configuration类的信息。在通过Configuration类新建StatementHandler接口实例。而StatementHandler接口实例就是用来处理生成Statement类的。很明显就是执行SQL语句就是在StatementHandler接口实例里面。

笔者来一个小结:动态代理的方式事实上最后还是动用SqlSession接口实例的方法。所以只有了解了SqlSession接口实例的方法就是可以进一步深入。而SqlSession接口实例执行方法的过程中又会去执行Executor类的方法。而关于Configuration类的作用可以说是任务时候都有可以初动用。当前最后的任务暂时是交给了Executor类的子类。

好了。到了这里面,关于SqlSession接口和Executor类的作用就有一个大概的像想空间。当然只望一下就明白SqlSession接口和Executor类的话,笔者觉得有一点难。至少笔者没有这样子的能力。在笔者看来SqlSession接口和Executor类的工作在doQuery方法的时候,就已经圆完的结束了。虽然笔者并没有说出SqlSession接口和Executor类的作用。主要还是靠你们自己去理解了。接下就来就是了解一下StatementHandler接口的作用。

SqlSession接口和Executor相关推荐

  1. Mybatis源码阅读(五 ):接口层——SqlSession

    *************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 如 ...

  2. Mybatis源码阅读(四):核心接口4.2——Executor(上)

    *************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 如 ...

  3. MyBatis核心源码剖析(SqlSession XML解析 Mapper executor SQL执行过程 自定义类型处理器 缓存 日志)

    MyBatis核心源码剖析 MyBatis核心源码剖析 1 MyBatis源码概述 1.1 为什么要看MyBatis框架的源码 1.2 如何深入学习MyBatis源码 1.3 源码分析的5大原则 2 ...

  4. 【笔记】mybatis的sqlSession和Mapper详解

    文章目录 SqlSession介绍和使用 Mapper映射器 总结 SqlSession介绍和使用 SqlSession是一个接口类,它类似于你们公司前台的美女客服,它扮演着门面的作用,而真正干活的是 ...

  5. Mybatis的SqlSession运行原理

    前言 SqlSession是Mybatis最重要的构建之一,可以简单的认为Mybatis一系列的配置目的是生成类似 JDBC生成的Connection对象的SqlSession对象,这样才能与数据库开 ...

  6. 手写自己的MyBatis框架-Executor

    到了sqlSession 的selectOne()方法,这里我们要去调用Executor 的query()方法,这个时候我们必须传入SQL 语句和参数(根据statementId 获取). 问题来了: ...

  7. mybatis源码阅读(一):SqlSession和SqlSessionFactory

    转载自  mybatis源码阅读(一):SqlSession和SqlSessionFactory 一.接口定义 听名字就知道这里使用了工厂方法模式,SqlSessionFactory负责创建SqlSe ...

  8. mybatis源码_Mybatis源码之SqlSession

    SqlSession简介 Mybatis是一个强大的ORM框架,它通过接口式编程为开发者屏蔽了传统JDBC的诸多不便,以简单的方式提供强大的扩展能力.其中的接口式编程就是指日常使用的Mapper接口, ...

  9. SqlSessionTemplate是如何保证MyBatis中SqlSession的线程安全的?

    2019独角兽企业重金招聘Python工程师标准>>> 一.DefaultSqlSession的线程不安全性 在MyBatis架构中SqlSession是提供给外层调用的顶层接口,实 ...

最新文章

  1. 外媒:华为有望最早于2021年推出自动驾驶汽车
  2. Android中的Menu和对话框形式的Activity
  3. php爬取ckplayer,CKplayer站外调用示例附最终效果
  4. [WC2018]通道
  5. 常用数据库语句(更新)
  6. 跟我一起写 Makefile(十一)
  7. 当Bert遇上Keras:这可能是Bert最简单的打开姿势
  8. Angular2 组件与模板 -- 输入和输出属性
  9. DrawImage内存不足问题
  10. centos mysql jar 驱动包_JDBC连接MySQL的数据库
  11. 机器学习与计算机视觉(计算机视觉的嵌入式平台)
  12. 30余种加密编码类型的密文特征分析
  13. 鸟瞰 Java 并发框架
  14. CodeForces - 976C(结构体排序思维)
  15. 吉他扒和弦 扒谱工具Riffstation
  16. WPF 自定义 写实风 雷达图控件
  17. 小白如何通俗地理解 - - 遗传算法以及其实际应用?
  18. 期货术语-关于升、贴水,点价,洗船
  19. ios绘图教程(原文http://www.cocoachina.com/industry/20140115/7703.html)
  20. AI智能安防视频融合云平台EasyCVR分屏播放不能正常使用是什么原因?

热门文章

  1. ubuntu下的常见12个命令---欢迎补充
  2. matlab feedforward,Matlab BP神经网络工具箱之feedforwardnet使用小结
  3. 普通的测试员和牛逼的测试员有什么区别?完成这两次跨越,你也可以
  4. 计算机制图的简称市什么,计算机地的图制图复习题.doc
  5. matlab状态空间法算反馈阵,matlab中已知系统的状态方程怎样绘制系统阶跃响应曲线...
  6. Java 压缩解压缩 第三方组件,推荐一个强大的Java开发工具类库!
  7. 死磕java_死磕 java同步系列之AQS起篇
  8. git .gitignore file does not work
  9. mel加载一个物体不同姿态的模型实现动画效果
  10. 柑橘黑斑病反射光谱特性与染病果实检测方法研究