Mybatis之二级缓存(八)
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之二级缓存(八)的更多相关文章
- Mybatis的二级缓存配置
一个项目中肯定会存在很多共用的查询数据,对于这一部分的数据,没必要每一个用户访问时都去查询数据库,因此配置二级缓存将是非常必要的. Mybatis的二级缓存配置相当容易,要开启二级缓存,只需要在你的 ...
- 使用Redis做MyBatis的二级缓存
使用Redis做MyBatis的二级缓存 通常为了减轻数据库的压力,我们会引入缓存.在Dao查询数据库之前,先去缓存中找是否有要找的数据,如果有则用缓存中的数据即可,就不用查询数据库了. 如果没有才去 ...
- MyBatis:二级缓存原理分析
MyBatis从入门到放弃七:二级缓存原理分析 前言 说起mybatis的一级缓存和二级缓存我特意问了几个身边的朋友他们平时会不会用,结果没有一个人平时业务场景中用. 好吧,那我暂且用来学习源码吧.一 ...
- Spring Boot + Mybatis + Redis二级缓存开发指南
Spring Boot + Mybatis + Redis二级缓存开发指南 背景 Spring-Boot因其提供了各种开箱即用的插件,使得它成为了当今最为主流的Java Web开发框架之一.Mybat ...
- Mybatis的二级缓存注意点
--声明:一下内容都不一定是正确的,只是自己测试的结果,请自己的动手操作得出自己的结论 1.开启Mybatis的二级缓存,不仅要在SqlMapConfig.xml中进行开启总开关,还要在对应的XXXM ...
- mybatis开启二级缓存小记
mybatis开启二级缓存小记 1.开启二级缓存 和一级缓存默认开启不一样,二级缓存需要我们手动开启 首先在全局配置文件 mybatis-configuration.xml 文件中加入如下代码: &l ...
- 《深入理解mybatis原理7》 MyBatis的二级缓存的设计原理
<深入理解mybatis原理> MyBatis的二级缓存的设计原理 MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分 ...
- 《深入理解mybatis原理》 MyBatis的二级缓存的设计原理
MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分析MyBatis的二级缓存的设计原理. 如上图所示,当开一个会话时,一个SqlS ...
- Redis实现Mybatis的二级缓存
一.Mybatis的缓存 通大多数ORM层框架一样,Mybatis自然也提供了对一级缓存和二级缓存的支持.一下是一级缓存和二级缓存的作用于和定义. 1.一级缓存是SqlSession级别的缓存.在操作 ...
随机推荐
- 如何形成自己的的绘画风格?/ Bookness插画教程分享
搬运地址 :http://wemedia.ifeng.com/46042525/wemedia.shtml ---------------------------------------------- ...
- NO7 利用三剑客awk-grep-sed-head-tail等7种方法实践
·seq sequence #序列·sed stream editor #(三剑客老二)流编辑器.实现对文件的增删改替换查. -n #取消默认输出.sed -n '20,30 ...
- 2020/2/21 fiyocms代码审计
0x00 前言 上午上了网课,一上午就装好了cms,下午还有网课,要是结束的早就进行审计. 解决了一下phpstudy使用过程中: Forbidden You don't have permissio ...
- return , return true , return false的区别
return true: 返回正确的处理结果. return false : 返回错误的处理结果 和 中断代码继续向下 执行. return: 返回null,起到中断方法执行的效果,只要不r ...
- ORIGIN(起源属性)路由起源骗术
ORIGIN(起源属性)配置: ①:抓取感兴趣流量——prefix.access ②:创建route-map 流量地图——permit 10 ③:匹配感兴趣流量——match ④:设置起源属性——se ...
- python面试题整理(一)
python基础:1.列表生成式和生成器表达式有什么区别 我说的是首先写法不一样,列表生成式用[],生成器表达式用(),其次列表生成是一次性生成一个完整的列表,生成器表达式返回的是一个一个的值,占用内 ...
- 72.Python中ORM聚合函数详解:Avg,aggregate,annotate
聚合函数: 如果你用原生SQL语句,则可以使用聚合函数提取数据.比如提取某个商品销售的数量,那么就可以使用Count,如果想要知道销售的平均价格,那么就可以使用Avg. 聚合函数是通过aggregat ...
- Django——优美的Path()函数
path( )作用:解析URL地址 path( ) 标准语法: (<>为必须的参数,[]为可选参数) path(<route>, <view>, [name=Non ...
- 032-session函数
<?php $username="guest1"; if(isset($username)) { session_name($username); } echo " ...
- 028-PHP常用数学函数abs和acos和asin
<?php print(abs(-));//打印绝对值 // 从 -1 到1打印acos函数的值 print("<TABLE BORDER=\"1\"> ...