1. 介绍

Mybatis缓存分为一级缓存和二级缓存,在本节中我们介绍下二级缓存的使用及其特性

MyBatis的一级缓存是在一个Session域内有效的,当Session关闭后,缓存内容也随之销毁。但是Mybatis的一级缓存在Spring中是没有作用的,而我们实际项目中也经常把Mybatis和Spring整合到一起使用。这个时候我们就需要用到二级缓存。

2. 准备

请先完成Mybatis之一级缓存(七)章节的内容。

3. Mybatis二级缓存学习

1) 开启二级缓存

Mybatis是默认不开启二级缓存的,要开启二级缓存我们需要做如下准备:

a. 调整Mybatis.xml,在<configuration>节点中增加<settings><setting name="cacheEnabled" value="true"></settings>。这里是Mybatis二级缓存的总开关。

<configuration>
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
.
.
.
</configuration>

b. 调整Mapper文件,开启针对Mapper的二级缓存开关。

<mapper namespace="com.mybatis.dao.CacheDao">
<cache eviction="FIFO" flushInterval="60000" size="1024" readOnly="true"/>
.
.
.
</mapper>

eviction="FIFO"  是缓存的淘汰算法,可选值有"LRU"、"FIFO"、"SOFT"、"WEAK",缺省值是LRU。

flushInterval="60000"  指缓存过期时间,单位为毫秒,缺省值为空,即只要容量足够,永不过期。

size="1024"  缓存容量。

readOnly="true"  是否只读。

如果为true, 则所有相同的sql返回的是同一个对象(有助于提高性能,但并发操作同一条数据时,可能不安全)。

如果为false,则所有相同的sql返回的是同一个对象的副本拷贝。

c. 调整要缓存的对象,使其实现com.io.Serializabie接口。

package com.mybatis.entity;

import java.io.Serializable;

public class CacheInfo implements Serializable{
.
.
.
}

2) 二级缓存的测试使用

package com.mybatis;

import java.io.InputStream;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; import com.mybatis.entity.CacheInfo; @SuppressWarnings("unused")
public class TestMain { public static void main(String[] args) {
InputStream iStream = TestMain.class.getClassLoader().getResourceAsStream("mybatis.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(iStream);
CacheInfo cacheInfo; SqlSession session1 = sessionFactory.openSession();
cacheInfo = session1.selectOne("com.mybatis.dao.CacheDao.getCache1", 1);
System.out.println("第1次打印 ID:"+cacheInfo.getId()+","+cacheInfo.getTxt());
session1.close(); SqlSession session2 = sessionFactory.openSession();
cacheInfo = session2.selectOne("com.mybatis.dao.CacheDao.getCache1", 1);
System.out.println("第1次打印 ID:"+cacheInfo.getId()+","+cacheInfo.getTxt());
session2.close(); }
}

打印结果为:

-- ::06.895 [DEBUG] com.mybatis.dao.CacheDao.getCache1 ==>  Preparing: SELECT * FROM tbCache1 WHERE ID=?
-- ::06.954 [DEBUG] com.mybatis.dao.CacheDao.getCache1 ==> Parameters: (Integer)
-- ::07.021 [DEBUG] com.mybatis.dao.CacheDao.getCache1 <== Total:
第1次打印 ID:,
.
.
.
-- ::07.021 [DEBUG] com.mybatis.dao.CacheDao Cache Hit Ratio [com.mybatis.dao.CacheDao]: 0.5
第2次打印 ID:,

从上面的结果中,可以看到“第2次打印”并没有从数据库中读取数据,而是直接读取的缓存。

4. 总结及其他

1)Mybatis的二级缓存可以跨Session访问,但是必须在同一个Session工厂内。

2)Mybatis的二级缓存更新是以Mapper(确切的说是namespace,因为Mybatis允许多个Mapper对用同一个namespace)为单位的,一个Mapper中的增删改查只能影响到当前Mapper所关联的缓存内容,不同Mapper之间的缓存是相互独立的。

3)Mybatis的二级缓存的弊端也就显而易见了。假如AMapper中是对A表的增删改查操作,BMapper中是对B表的增删改查操作,CMapper中执行了一个针对A表和B表的联合查找。那么,

首先,我们执行CMapper的联合查找,然后针对CMapper产生一个缓存对象。

然后,我们执行AMapper中对A表进行更新操作,由于二级缓存是针对Mapper为单位的,所以此时并不会更新CMapper中的缓存对象。

在这种情况下,我们再重新执行CMapper的联合查找(查询条件不变),就会读取CMapper中的二级缓存内容,也就会读到脏数据。

获取有人会说,我们可以把AMapper、BMapper、CMapper合并到一个Mapper中啊?这样会带来另外一些问题:

首先,这样会导致我们的单个的Mapper文件容量变得极大

其次,这样会导致这个融合后的Mapper对应的缓存文件不停的被更新,导致效率低下甚至失去缓存意义。

Mybatis之二级缓存(八)的更多相关文章

  1. Mybatis的二级缓存配置

    一个项目中肯定会存在很多共用的查询数据,对于这一部分的数据,没必要每一个用户访问时都去查询数据库,因此配置二级缓存将是非常必要的.  Mybatis的二级缓存配置相当容易,要开启二级缓存,只需要在你的 ...

  2. 使用Redis做MyBatis的二级缓存

    使用Redis做MyBatis的二级缓存 通常为了减轻数据库的压力,我们会引入缓存.在Dao查询数据库之前,先去缓存中找是否有要找的数据,如果有则用缓存中的数据即可,就不用查询数据库了. 如果没有才去 ...

  3. MyBatis:二级缓存原理分析

    MyBatis从入门到放弃七:二级缓存原理分析 前言 说起mybatis的一级缓存和二级缓存我特意问了几个身边的朋友他们平时会不会用,结果没有一个人平时业务场景中用. 好吧,那我暂且用来学习源码吧.一 ...

  4. Spring Boot + Mybatis + Redis二级缓存开发指南

    Spring Boot + Mybatis + Redis二级缓存开发指南 背景 Spring-Boot因其提供了各种开箱即用的插件,使得它成为了当今最为主流的Java Web开发框架之一.Mybat ...

  5. Mybatis的二级缓存注意点

    --声明:一下内容都不一定是正确的,只是自己测试的结果,请自己的动手操作得出自己的结论 1.开启Mybatis的二级缓存,不仅要在SqlMapConfig.xml中进行开启总开关,还要在对应的XXXM ...

  6. mybatis开启二级缓存小记

    mybatis开启二级缓存小记 1.开启二级缓存 和一级缓存默认开启不一样,二级缓存需要我们手动开启 首先在全局配置文件 mybatis-configuration.xml 文件中加入如下代码: &l ...

  7. 《深入理解mybatis原理7》 MyBatis的二级缓存的设计原理

    <深入理解mybatis原理> MyBatis的二级缓存的设计原理 MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分 ...

  8. 《深入理解mybatis原理》 MyBatis的二级缓存的设计原理

    MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分析MyBatis的二级缓存的设计原理. 如上图所示,当开一个会话时,一个SqlS ...

  9. Redis实现Mybatis的二级缓存

    一.Mybatis的缓存 通大多数ORM层框架一样,Mybatis自然也提供了对一级缓存和二级缓存的支持.一下是一级缓存和二级缓存的作用于和定义. 1.一级缓存是SqlSession级别的缓存.在操作 ...

随机推荐

  1. JuJu团队12月1号工作汇报

    JuJu团队12月1号工作汇报 JuJu   Scrum 团队成员 今日工作 剩余任务 困难 于达  修改generator函数  优化代码  不熟悉julia 婷婷 和金华一起调试main.jl 继 ...

  2. 51nod 1352:集合计数

    1352 集合计数 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 给出N个固定集合{1,N},{2,N-1},{3,N-2},...,{N-1,2 ...

  3. GNS3 模拟icmp端口不可达

    R1 : conf t int f0/0 no shutdown ip add 192.168.1.1 255.255.255.0 no ip routing end R2 f0/0: conf t ...

  4. 根据上传的MultipartFile通过springboot转化为File类型并调用通过File文件流的方法上传特定服务器

      @PostMapping("uploadExcel") public ResponseObj uploadExcel(@RequestParam("excelFile ...

  5. cf 782# A.Andryusha and Socks B.The Meeting Place Cannot Be Changed C.Andryusha and Colored Balloons

    看来快掉到灰名的蒟蒻涨rating也快... A题模拟一下就好(一开始还sb,, #include<bits/stdc++.h> #define LL long long using na ...

  6. 报错盲注之exp注入(double数值类型溢出原理详解)

    首先感谢原文博主,在此致敬.本文转自:http://www.cnblogs.com/lcamry/articles/5509124.html Exp()为以 e 为底的对数函数:MySQL版本在 5. ...

  7. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-barcode

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  8. springboot - 使用ErrorAttributes 在我们自定义的 ErrorController中

    1.概览 基于<springboot - 映射 /error 到自定义且实现了ErrorController的Controller>改造,仅将MyCustomErrorController ...

  9. [BJDCTF2020]ZJCTF,不过如此

    0x00 知识点 本地文件包含伪协议 ?text=php://input //执行 post: I have a dream ?file=php://filter/read/convert.base6 ...

  10. Android数据库(sqlite)之Room

    说在前面: 1.使用Room需要添加的依赖: dependencies { def room_version = "2.2.3" implementation "andr ...