前面几篇博客我们介绍了Excutor及抽象类BaseExecutor和实现类SimpleExecutor、BatchExecutor和ReuseExecutor:

博客列表:

Mybatis执行Executor(一)

Mybatis执行BaseExecutor(二)

Mybatis执行SimpleExecutor(三)

Mybatis执行BatchExecutor(四)

Mybatis执行ReuseExecutor(五)

接下来我们再介绍一个比较重要的类CachingExecutor,通过类名我们可以猜测到,这个Executor执行类是使用内存的,将数据保存到缓存中,这样可以有效的解决增删改查性能。缓存的作用域为mapper(namespace),所以同一个namespace的操作会影响到相同作用域下的缓存,这样不同的域对同一个表进行操作很有可能导致缓存中的数据不一样,出现问题,还是不推荐使用。

  1. public class CachingExecutor implements Executor {
  2.  
  3. private Executor delegate;
  4. private TransactionalCacheManager tcm = new TransactionalCacheManager();
  5.  
  6. public CachingExecutor(Executor delegate) {
  7. this.delegate = delegate;
  8. delegate.setExecutorWrapper(this);
  9. }
  10.  
  11. public Transaction getTransaction() {
  12. return delegate.getTransaction();
  13. }
  14.  
  15. public void close(boolean forceRollback) {
  16. try {
  17. //issues #499, #524 and #573
  18. if (forceRollback) {
  19. tcm.rollback();
  20. } else {
  21. tcm.commit();
  22. }
  23. } finally {
  24. delegate.close(forceRollback);
  25. }
  26. }
  27. //是否关闭了executor
  28. public boolean isClosed() {
  29. return delegate.isClosed();
  30. }
  31.  
  32. public int update(MappedStatement ms, Object parameterObject) throws SQLException {
  33. //是否需要更缓存
  34. flushCacheIfRequired(ms);
  35. //更新数据
  36. return delegate.update(ms, parameterObject);
  37. }
  38.  
  39. public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
  40. BoundSql boundSql = ms.getBoundSql(parameterObject);
  41. //创建缓存值
  42. CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
  43. //获取记录
  44. return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  45. }
  46.  
  47. public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
  48. throws SQLException {
  49. //获取缓存
  50. Cache cache = ms.getCache();
  51. //如果设置保存到缓存
  52. if (cache != null) {
  53. flushCacheIfRequired(ms);
  54. if (ms.isUseCache() && resultHandler == null) {
  55. ensureNoOutParams(ms, parameterObject, boundSql);
  56. @SuppressWarnings("unchecked")
  57. //从缓存中获取数据
  58. List<E> list = (List<E>) tcm.getObject(cache, key);
  59. //为空执行一次,将结果保存到缓存中
  60. if (list == null) {
  61. list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  62. tcm.putObject(cache, key, list); // issue #578. Query must be not synchronized to prevent deadlocks
  63. }
  64. return list;
  65. }
  66. }
  67. return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  68. }
  69.  
  70. public List<BatchResult> flushStatements() throws SQLException {
  71. return delegate.flushStatements();
  72. }
  73.  
  74. public void commit(boolean required) throws SQLException {
  75. delegate.commit(required);
  76. tcm.commit();
  77. }
  78.  
  79. public void rollback(boolean required) throws SQLException {
  80. try {
  81. delegate.rollback(required);
  82. } finally {
  83. if (required) {
  84. tcm.rollback();
  85. }
  86. }
  87. }
  88.  
  89. private void ensureNoOutParams(MappedStatement ms, Object parameter, BoundSql boundSql) {
  90. if (ms.getStatementType() == StatementType.CALLABLE) {
  91. for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {
  92. if (parameterMapping.getMode() != ParameterMode.IN) {
  93. throw new ExecutorException("Caching stored procedures with OUT params is not supported. Please configure useCache=false in " + ms.getId() + " statement.");
  94. }
  95. }
  96. }
  97. }
  98.  
  99. public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {
  100. return delegate.createCacheKey(ms, parameterObject, rowBounds, boundSql);
  101. }
  102.  
  103. public boolean isCached(MappedStatement ms, CacheKey key) {
  104. return delegate.isCached(ms, key);
  105. }
  106.  
  107. public void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType) {
  108. delegate.deferLoad(ms, resultObject, property, key, targetType);
  109. }
  110.  
  111. public void clearLocalCache() {
  112. delegate.clearLocalCache();
  113. }
  114.  
  115. private void flushCacheIfRequired(MappedStatement ms) {
  116. Cache cache = ms.getCache();
  117. if (cache != null && ms.isFlushCacheRequired()) {
  118. tcm.clear(cache);
  119. }
  120. }
  121.  
  122. @Override
  123. public void setExecutorWrapper(Executor executor) {
  124. throw new UnsupportedOperationException("This method should not be called");
  125. }
  126.  
  127. }

Mybatis执行CachingExecutor(六)的更多相关文章

  1. Springboot中mybatis执行逻辑源码分析

    Springboot中mybatis执行逻辑源码分析 在上一篇springboot整合mybatis源码分析已经讲了我们的Mapper接口,userMapper是通过MapperProxy实现的一个动 ...

  2. mybatis执行批量更新update

    Mybatis的批量插入这里有http://ljhzzyx.blog.163.com/blog/static/38380312201353536375/.目前想批量更新,如果update的值是相同的话 ...

  3. 一图看懂mybatis执行过程

    一图看懂mybatis执行过程,不再懵B了

  4. 【mybatis】mybatis执行一个update方法,返回值为1,但是数据库中数据并未更新,粘贴sql语句直接在数据库执行,等待好久报错:Lock wait timeout exceeded; try restarting transaction

    今天使用mybatis和jpa的过程中,发现这样一个问题: mybatis执行一个update方法,返回值为1,但是数据库中数据并未更新,粘贴sql语句直接在数据库执行,等待好久报错:Lock wai ...

  5. mybatis执行多条sql语句

    1,mybatis执行多条sql语句,有以下几种思路, a,存储过程 b,修改jdbc的参数,允许执行多条语句,如下所示: sqlserver可以直接使用begin,end来执行多条语句, mysql ...

  6. mybatis执行过程及经典面试题

    Mybatis执行流程 mybatis中xml解析是通过SqlSessionFactoryBuilder.build()方法. 初始化mybatis(解析xml文件构建成Configuration对象 ...

  7. mybatis 逆向工程(通过数据库表针对单表自动生成mybatis执行所需要的代码)

    mybatis需要程序员自己编写sql语句,mybatis官方提供逆向工程,可以针对单表自动生成mybatis执行所需要的代码(mapper.java.mapper.xml.pojo…),可以让程序员 ...

  8. mybatis 执行流程以及初用错误总结

    mappper 配置文件  头文件: 1.   <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" &q ...

  9. MyBatis执行流程的各阶段介绍

    目录 一.mybatis极简示例 1.1 创建mybatis配置文件 1.2 创建数据库表 1.3 创建javabean 1.4 创建mapper映射文件 1.5 运行测试 二.mybatis的几大“ ...

随机推荐

  1. tensorflow rnn 最简单实现代码

    tensorflow rnn 最简单实现代码 #!/usr/bin/env python # -*- coding: utf-8 -*- import tensorflow as tf from te ...

  2. 好久没用IJ写Java 之 《求输入的一个数中包含奇数、偶数、零的个数》

    /** *Created by xuzili at 22:12 on 2018/4/4 */ // 以上注释使用了IntelliJ Idea的File-Settings-Editor-Live Tem ...

  3. SCNN车道线检测--(SCNN)Spatial As Deep: Spatial CNN for Traffic Scene Understanding(论文解读)

    Spatial As Deep: Spatial CNN for Traffic Scene Understanding 收录:AAAI2018 (AAAI Conference on Artific ...

  4. Mac Webview OC与JS交互实现

    1.首先,需要定义一个JS可识别的变量(如external)用于OC与JS交互 - (void)webView:(WebView *)sender didClearWindowObject:(WebS ...

  5. C指针 指针和数组 二维数组的指针 指针应用

    直接到变量名标识的存储单元中读取变量的值--直接寻址 通过其他变量间接找到变量的地址读取变量的值--间接寻址 指针变量存放地址 显示变量的地址 指针变量使用前必须初始化,若不知指向哪,可先指向NULL ...

  6. 数组查找算法的C语言 实现-----线性查找和二分查找

    线性查找  Linear Search 用户输入学生学号的成绩 二分查找  Binary Search 要求数据表是已经排好序的 程序存在小的瑕疵

  7. spark on yarn 运行问题记录

    问题一: 18/03/15 07:59:23 INFO yarn.Client: client token: N/A diagnostics: Application application_1521 ...

  8. 彻底理解Oracle中的集合操作与复合查询

    --Oracle中的复合查询 复合查询:包含集合运算(操作)的查询 常见的集合操作有: union: 两个查询的并集(无重复行.按第一个查询的第一列升序排序) union all:两个查询的并集(有重 ...

  9. Oracle中的列转行例子详解

    数据如下:name id张三 1,2,3 要求实现:name id张三 1张三 2张三 3 --创建临时表 create table tmp as(select '张三' name, '1,2,3' ...

  10. machine learning 之 Neural Network 1

    整理自Andrew Ng的machine learning课程week 4. 目录: 为什么要用神经网络 神经网络的模型表示 1 神经网络的模型表示 2 实例1 实例2 多分类问题 1.为什么要用神经 ...