Mybatis第八篇【一级缓存、二级缓存、与ehcache整合】
Mybatis缓存
缓存的意义
- 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
mybatis提供一级缓存和二级缓存
- mybatis一级缓存是一个SqlSession级别,sqlsession只能访问自己的一级缓存的数据
- 二级缓存是跨sqlSession,是mapper级别的缓存,对于mapper级别的缓存不同的sqlsession是可以共享的。
看完上面对Mybatis的缓存的解释,我们发现Mybatis的缓存和Hibernate的缓存是极为相似的..
Mybatis一级缓存
Mybatis的一级缓存原理:
第一次发出一个查询sql,sql查询结果写入sqlsession的一级缓存中,缓存使用的数据结构是一个map
Mybatis二级缓存
二级缓存原理:
二级缓存的范围是mapper级别(mapper同一个命名空间),mapper以命名空间为单位创建缓存数据结构,结构是map
Mybatis二级缓存配置
需要我们在Mybatis的配置文件中配置二级缓存
<!-- 全局配置参数 -->
<settings>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
上面已经说了,二级缓存的范围是mapper级别的,因此我们的Mapper如果要使用二级缓存,还需要在对应的映射文件中配置..
<cache/>
查询结果映射的pojo序列化
mybatis二级缓存需要将查询结果映射的pojo实现 java.io.serializable接口,如果不实现则抛出异常:
org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: cn.itcast.mybatis.po.User
二级缓存可以将内存的数据写到磁盘,存在对象的序列化和反序列化,所以要实现java.io.serializable接口。
如果结果映射的pojo中还包括了pojo,都要实现java.io.serializable接口。
禁用二级缓存
对于变化频率较高的sql,需要禁用二级缓存:
在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。、、
<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">
刷新缓存
有的同学到这里可能会有一个疑问:为什么缓存我们都是在查询语句中配置??而使用增删改的时候,缓存默认就会被清空【刷新了】???
缓存其实就是为我们的查询服务的,对于增删改而言,如果我们的缓存保存了增删改后的数据,那么再次读取时就会读到脏数据了!
我们在特定的情况下,还可以单独配置刷新缓存【但不建议使用】flushCache
<update id="updateUser" parameterType="cn.itcast.mybatis.po.User" flushCache="false">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
了解Mybatis缓存的一些参数
mybatis的cache参数只适用于mybatis维护缓存。
flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。
readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
如下例子:
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会导致冲突。可用的收回策略有, 默认的是 LRU:
1.LRU – 最近最少使用的:移除最长时间不被使用的对象。
2.FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
3.SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
4.WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
mybatis和ehcache缓存框架整合
ehcache是专门用于管理缓存的,Mybatis的缓存交由ehcache管理会更加得当..
在mybatis中提供一个cache接口,只要实现cache接口就可以把缓存数据灵活的管理起来。
整合jar包
- mybatis-ehcache-1.0.2.jar
- ehcache-core-2.6.5.jar
ehcache对cache接口的实现类:
ehcache.xml配置信息
这个xml配置文件是配置全局的缓存管理方案
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!--diskStore:缓存数据持久化的目录 地址 -->
<diskStore path="F:\develop\ehcache" />
<defaultCache
maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="false"
diskPersistent="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
如果我们Mapper想单独拥有一些特性,需要在mapper.xml中单独配置
<!-- 单位:毫秒 -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache">
<property name="timeToIdleSeconds" value="12000"/>
<property name="timeToLiveSeconds" value="3600"/>
<!-- 同ehcache参数maxElementsInMemory -->
<property name="maxEntriesLocalHeap" value="1000"/>
<!-- 同ehcache参数maxElementsOnDisk -->
<property name="maxEntriesLocalDisk" value="10000000"/>
<property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>
应用场景与局限性
应用场景
对查询频率高,变化频率低的数据建议使用二级缓存。
对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度
业务场景比如:
- 耗时较高的统计分析sql、
- 电话账单查询sql等。
实现方法如下:通过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,比如设置为30分钟、60分钟、24小时等,根据需求而定。
局限性
mybatis局限性
mybatis二级缓存对细粒度的数据级别的缓存实现不好,比如如下需求:对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次都能查询最新的商品信息,此时如果使用mybatis的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,因为mybaits的二级缓存区域以mapper为单位划分,当一个商品信息变化会将所有商品信息的缓存数据全部清空。解决此类问题需要在业务层根据需求对数据有针对性缓存。
Mybatis第八篇【一级缓存、二级缓存、与ehcache整合】的更多相关文章
- mybatis学习--缓存(一级和二级缓存)
声明:学习摘要! MyBatis缓存 我们知道,频繁的数据库操作是非常耗费性能的(主要是因为对于DB而言,数据是持久化在磁盘中的,因此查询操作需要通过IO,IO操作速度相比内存操作速度慢了好几个量级) ...
- Mybatis一级、二级缓存
Mybatis一级.二级缓存 一级缓存 首先做一个测试,创建一个mapper配置文件和mapper接口,我这里用了最简单的查询来演示. <mapper namespace="c ...
- MyBatis(七):MyBatis缓存详解(一级缓存/二级缓存)
一级缓存 MyBatis一级缓存上SqlSession缓存,即在统一SqlSession中,在不执行增删改操作提交事务的前提下,对同一条数据进行多次查询时,第一次查询从数据库中查询,完成后会存入缓 ...
- Mybatis源码分析之Cache二级缓存原理 (五)
一:Cache类的介绍 讲解缓存之前我们需要先了解一下Cache接口以及实现MyBatis定义了一个org.apache.ibatis.cache.Cache接口作为其Cache提供者的SPI(Ser ...
- Hibernate 再接触 一级缓存 二级缓存 查询缓存
缓存 就是把本来应该放在硬盘里的东西放在内存里 将来存内存里读 一级缓存: session缓存 二级缓存: sessionFactory级别的 (适合经常访问,数据量有限,改动不大) 很多的se ...
- hibernate的获取session的两方法比较,和通过id获取对象的比较,一级缓存二级缓存
opensession与currentsession的联系与区别 在同一个线程中opensession的session是不一样的,而currentsession获取的session是一样的,这就保证了 ...
- mybatis一级缓存二级缓存
一级缓存 Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言.所以在参数和SQL完全一样的情况下,我们使用同一个SqlSess ...
- mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache
1.1 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 s ...
- 【mybatis源码学习】mybtias一级,二级缓存
转载:https://www.cnblogs.com/ysocean/p/7342498.html mybatis 为我们提供了一级缓存和二级缓存,可以通过下图来理解: ①.一级缓存是SqlSessi ...
随机推荐
- shell中while循环的陷阱
在写while循环的时候,发现了一个问题,在while循环内部对变量赋值.定义变量.数组定义等等环境,在循环外面失效. 一个简单的测试脚本如下: #!/bin/bash echo "abc ...
- .Net Framework下对Dapper二次封装迁移到.Net Core2.0遇到的问题以及对Dapper的封装介绍
今天成功把.Net Framework下使用Dapper进行封装的ORM成功迁移到.Net Core 2.0上,在迁移的过程中也遇到一些很有意思的问题,值得和大家分享一下.下面我会还原迁移的每一个过程 ...
- ABP module-zero +AdminLTE+Bootstrap Table+jQuery权限管理系统第十二节--小结,Bootstrap Table之角色管理
返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 很多人说ABP不适合高并发大型,有一定的道理,但是我觉得还是可以的,就看架构师的能力了,哈哈,我之前公司就是ABP ...
- linux下mysql忘记密码的解决方案
1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库. 因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的 状态下,其他的用户也可以任意地 ...
- centos开放端口8080
今天购买了云服务器,玩耍一下,配置好了jdk和tomcat后,发现访问不了8080端口,telnet 不通,由此想到了防火墙挡住了. 配置规则: iptables -I INPUT -p tcp -- ...
- Maven 项目 @Override must override a superclass method` 问题
问题 Maven 项目 @Override must override a superclass method` 原因 JDK 在1.5以上的版本,才支持@Override 注解 解决方法 (1)po ...
- Java基础---泛型、集合框架工具类:collections和Arrays
第一讲 泛型(Generic) 一.概述 1.JDK1.5版本以后出现的新特性.用于解决安全问题,是一个类型安全机制. 2.JDK1.5的集合类希望在定义集合时,明确表明你要向集合中装入那种类 ...
- Windows下Docker承载ASP.NET Core 应用
基本配置: Win7 64系统,Docker Toolbox, 主要步骤: [1]发布ASP.NET Core MVC应用,CD到项目根目录,执行dontnet publish [2]新建一个Dock ...
- echarts柱状图修改背景线为网格线、去掉刻度标签、鼠标悬停在柱条上时变色、柱条圆角弧度、
option = { color: ['red'],//修改柱条颜色 tooltip : { triggerOn:'mousemove' }, grid: { left: '3%', right: ' ...
- vue项目引入bootstrap、jquery
在进行vue的学习,项目中需要引入bootstrap.jquery的步骤. 一.引入jQuery 在当前项目的目录下(就是package.json),运行命令 cnpm install jquery ...