https://www.cnblogs.com/liouwei4083/p/6025929.html

mybatis 二级缓存不推荐使用

一 mybatis的缓存使用。

大体就是首先根据你的sqlid,参数的信息自己算出一个key值,然后你查询的时候,会先把这个key值去缓存中找看有没有value,如果有,直接返回出来,就不查询db了。如果没有,那么查询db,然后将key,value保存到缓存中,以便下次使用。

1.1mybatis的一级缓存是基于sqlsession为生命周期的

当你这个session没有了,缓存就没有了,其次当你sql执行!isselect语句的时候,缓存也会被直接全部清理掉以保证数据一致性。
  public int update(MappedStatement ms, Object parameter) throws SQLException {
ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
if (closed) throw new ExecutorException("Executor was closed.");
//清理缓存
clearLocalCache();
return doUpdate(ms, parameter);
}

1.2 mybatis的二级缓存是基于application为生命周期的

范围是按照每个namepace一个缓存来存贮和维护,同一个namespace放到一个缓存对象中,当这个namaspace中执行了!isselect语句的时候,整个namespace中的缓存全部清除掉。
  public int update(MappedStatement ms, Object parameterObject) throws SQLException {
//清理缓存,并且!isselect语句的flushcache都是默认为true的。
flushCacheIfRequired(ms);
return delegate.update(ms, parameterObject);
}
 
以下摘抄自网络观点文字  http://blog.csdn.net/isea533/article/details/44566257

三、Cache使用时的注意事项

1. 只能在【只有单表操作】的表上使用缓存

不只是要保证这个表在整个系统中只有单表操作,而且和该表有关的全部操作必须全部在一个namespace下。

2. 在可以保证查询远远大于insert,update,delete操作的情况下使用缓存

这一点不需要多说,所有人都应该清楚。记住,这一点需要保证在1的前提下才可以!

四、避免使用二级缓存

可能会有很多人不理解这里,二级缓存带来的好处远远比不上他所隐藏的危害。

缓存是以namespace为单位的,不同namespace下的操作互不影响。

insert,update,delete操作会清空所在namespace下的全部缓存。

通常使用MyBatis Generator生成的代码中,都是各个表独立的,每个表都有自己的namespace。

为什么避免使用二级缓存

在符合【Cache使用时的注意事项】的要求时,并没有什么危害。

其他情况就会有很多危害了。

针对一个表的某些操作不在他独立的namespace下进行。

例如在UserMapper.xml中有大多数针对user表的操作。但是在一个XXXMapper.xml中,还有针对user单表的操作。

这会导致user在两个命名空间下的数据不一致。如果在UserMapper.xml中做了刷新缓存的操作,在XXXMapper.xml中缓存仍然有效,如果有针对user的单表查询,使用缓存的结果可能会不正确。

更危险的情况是在XXXMapper.xml做了insert,update,delete操作时,会导致UserMapper.xml中的各种操作充满未知和风险。

有关这样单表的操作可能不常见。但是你也许想到了一种常见的情况。

多表操作一定不能使用缓存

为什么不能?

首先不管多表操作写到那个namespace下,都会存在某个表不在这个namespace下的情况。

例如两个表:role和user_role,如果我想查询出某个用户的全部角色role,就一定会涉及到多表的操作。

<select id="selectUserRoles" resultType="UserRoleVO">
select * from user_role a,role b where a.roleid = b.roleid and a.userid = #{userid}
</select>
像上面这个查询,你会写到那个xml中呢??

不管是写到RoleMapper.xml还是UserRoleMapper.xml,或者是一个独立的XxxMapper.xml中。如果使用了二级缓存,都会导致上面这个查询结果可能不正确。

如果你正好修改了这个用户的角色,上面这个查询使用缓存的时候结果就是错的。

这点应该很容易理解。

在我看来,就以MyBatis目前的缓存方式来看是无解的。多表操作根本不能缓存。

如果你让他们都使用同一个namespace(通过<cache-ref>)来避免脏数据,那就失去了缓存的意义。

看到这里,实际上就是说,二级缓存不能用。整篇文章介绍这么多也没什么用了。

五、挽救二级缓存?

想更高效率的使用二级缓存是解决不了了。

但是解决多表操作避免脏数据还是有法解决的。解决思路就是通过拦截器判断执行的sql涉及到那些表(可以用jsqlparser解析),然后把相关表的缓存自动清空。但是这种方式对缓存的使用效率是很低的。

设计这样一个插件是相当复杂的,既然我没想着去实现,就不废话了。

最后还是建议,放弃二级缓存,在业务层使用可控制的缓存代替更好。

Mybatis 为什么不要用二级缓存的更多相关文章

  1. mybatis 使用redis实现二级缓存(spring boot)

    mybatis 自定义redis做二级缓存 前言 如果关注功能实现,可以直接看功能实现部分 何时使用二级缓存 一个宗旨---不常变的稳定而常用的 一级是默认开启的sqlsession级别的. 只在单表 ...

  2. Mybatis整合Redis实现二级缓存

    Mybatis集成ehcache . 为什么需要缓存 拉高程序的性能 . 什么样的数据需要缓存 很少被修改或根本不改的数据 业务场景比如:耗时较高的统计分析sql.电话账单查询sql等 . ehcac ...

  3. Mybatis架构原理(二)-二级缓存源码剖析

    Mybatis架构原理(二)-二级缓存源码剖析 二级缓存构建在一级缓存之上,在收到查询请求时,Mybatis首先会查询二级缓存,若二级缓存没有命中,再去查询一级缓存,一级缓存没有,在查询数据库; 二级 ...

  4. mybatis结合redis实战二级缓存(六)

    之前的文章中我们意见分析了一级缓存.二级缓存的相关源码和基本原理,今天我们来分享下了mybatis二级缓存和redis的结合,当然mybatis二级缓存也可以和ehcache.memcache.OSC ...

  5. SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置

    2016年03月03日 10:37:47 标签: mysql / redis / mybatis / spring mvc / spring 33805 项目环境: 在SpringMVC + MyBa ...

  6. SpringBank 开发日志 Mybatis 使用redis 作为二级缓存时,无法通过cacheEnabled=false 将其关闭

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...

  7. Mybatis五(一级二级缓存、第三方缓存)

    一级缓存 Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言.所以在参数和SQL完全一样的情况下,我们使用同一个SqlSess ...

  8. mybatis结合redis实战二级缓存

    之前的文章中我们意见分析了一级缓存.二级缓存的相关源码和基本原理,今天我们来分享下了mybatis二级缓存和redis的结合,当然mybatis二级缓存也可以和ehcache.memcache.OSC ...

  9. mybatis由浅入深day02_7.3二级缓存

    7.3 二级缓存 7.3.1 原理 下图是多个sqlSession请求UserMapper的二级缓存图解. 首先开启mybatis的二级缓存. sqlSession1去查询用户id为1的用户信息,查询 ...

随机推荐

  1. UVA 10305:Ordering Tasks(拓扑排序)

    #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm& ...

  2. solrcloud配置中文分词器ik

    无论是solr还是luncene,都对中文分词不太好,所以我们一般索引中文的话需要使用ik中文分词器. 三台机器(192.168.1.236,192.168.1.237,192.168.1.238)已 ...

  3. Java Mail多人群发与多附件发送

        近期公司的项目用到了Java Mail来发送注冊邮件,只是.开发的时候都是使用封装好的JAR,曾经也不是非常了解Java Mail的使用原理. 网上非常多代码都是仅仅有一部分,看一看也跑不起来 ...

  4. 基于windows IIS的C语言CGI WEB服务器环境搭建

    网页编程对我来说特别亲切,因为我就是从html.ASP.PHP一步步接触编程的.自己的编程爱好也是从那里一点一点被满足.不过离开大学之后很久没有碰过WEB了,最近看到嵌入式中的涉及到的web服务器,了 ...

  5. HIVE之 Sqoop 1.4.6 安装、hive与oracle表互导

    1. sqoop数据迁移 1.1 概述 sqoop是apache旗下一款“Hadoop和关系数据库服务器之间传送数据”的工具. 导入数据:MySQL,Oracle导入数据到Hadoop的HDFS.HI ...

  6. 教你如何阅读Oracle数据库官方文档

    < Ask Oracle官方原创 > Oracle 官方文档 数量庞大,而且往往没有侧重点,让oracle新手看起来很费力.但是,仍有很多Oracle使用者认为任何oracle学习资料都比 ...

  7. OAuth 2.0:Bearer Token、MAC Token区别

    Access Token 类型介绍 介绍两种类型的Access Token:Bearer类型和MAC类型 区别项 Bearer Token MAC Token 1 (优点) 调用简单,不需要对请求进行 ...

  8. commonJS、AMD、es模块化 区别(表格比较)

    commonJS.AMD.es6模块化 区别(表格比较): table th:first-of-type { } table th:nth-of-type(3) { width: 150px; } t ...

  9. 使用js提交form表单的两种方法

    提交form表单的时候瑶族一些简单的验证,验证完后才能提交,避免无效提交. 1.当输入用户名和密码为空的时候,需要判断.这时候就用到了校验用户名和密码,这个需要在前端页面写:有两种方法,一种是用sub ...

  10. sklearn, Numpy以及Pandas

    pandas里面的对于数据操作比如where,drop以及dropna等都会有一个属性:inplace,这个单词意思是原地,如果inplace=true代表数据本身要执行该操作:如果inplace=f ...