1 缓存的意义

将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
2 mybatis持久层缓存
mybatis提供一级缓存和二级缓存
mybatis一级缓存是一个SqlSession级别,sqlsession只能访问自己的一级缓存的数据,二级缓存是跨sqlSession,是mapper级别的缓存,对于mapper级别的缓存不同的sqlsession是可以共享的。
3 一级缓存
3.1 原理
第一次发出一个查询sql,sql查询结果写入sqlsession的一级缓存中,缓存使用的数据结构是一个map<key,value>
key:hashcode+sql+sql输入参数+输出参数(sql的唯一标识)
value:用户信息
同一个sqlsession再次发出相同的sql,就从缓存中取不走数据库。如果两次中间出现commit操作(修改、添加、删除),本sqlsession中的一级缓存区域全部清空,下次再去缓存中查询不到所以要从数据库查询,从数据库查询到再写入缓存。
每次查询都先从缓存中查询:
如果缓存中查询到则将缓存数据直接返回。
如果缓存中查询不到就从数据库查询:
3.2 一级缓存配置
mybatis默认支持一级缓存不需要配置。
注意:mybatis和spring整合后进行mapper代理开发,不支持一级缓存,mybatis和spring整合,spring按照mapper的模板去生成mapper代理对象,模板中在最后统一关闭sqlsession。
3.3 一级缓存测试
//一级缓存
@Test
public void testCache1() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//第一次查询用户id为1的用户
User user = userMapper.findUserById(1);
System.out.println(user);
//中间修改用户要清空缓存,目的防止查询出脏数据
/*user.setUsername("测试用户2");
userMapper.updateUser(user);
sqlSession.commit();*/
//第二次查询用户id为1的用户
User user2 = userMapper.findUserById(1);
System.out.println(user2);
sqlSession.close();
}
4 二级缓存
4.1 原理
二级缓存的范围是mapper级别(mapper同一个命名空间),mapper以命名空间为单位创建缓存数据结构,结构是map<key、value>。
每次查询先看是否开启二级缓存,如果开启从二级缓存的数据结构中取缓存数据,
如果从二级缓存没有取到,再从一级缓存中找,如果一级缓存也没有,从数据库查询。
4.2 mybatis二级缓存配置
在核心配置文件SqlMapConfig.xml中加入
<setting name="cacheEnabled" value="true"/>
要在你的Mapper映射文件中添加一行: <cache /> ,表示此mapper开启二级缓存。
4.3 查询结果映射的pojo序列化
mybatis二级缓存需要将查询结果映射的pojo实现 Java.io.serializable接口,如果不实现则抛出异常:
org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: com.sihai.mybatis.po.User
二级缓存可以将内存的数据写到磁盘,存在对象的序列化和反序列化,所以要实现java.io.serializable接口。
如果结果映射的pojo中还包括了pojo,都要实现java.io.serializable接口。
4.4 二级缓存禁用
对于变化频率较高的sql,需要禁用二级缓存:
在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。
<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">
4.5 刷新缓存
如果sqlsession操作commit操作,对二级缓存进行刷新(全局清空)。
设置statement的flushCache是否刷新缓存,默认值是true。
4.6 测试代码
//二级缓存的测试
@Test
public void testCache2() throws Exception {
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
SqlSession sqlSession3 = sqlSessionFactory.openSession();
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class);
//第一次查询用户id为1的用户
User user = userMapper1.findUserById(1);
System.out.println(user);
sqlSession1.close();
//中间修改用户要清空缓存,目的防止查询出脏数据
/*user.setUsername("测试用户2");
userMapper3.updateUser(user);
sqlSession3.commit();
sqlSession3.close();*/
//第二次查询用户id为1的用户
User user2 = userMapper2.findUserById(1);
System.out.println(user2);
sqlSession2.close();
}
4.7 mybatis的cache参数
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 – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
5 mybatis和ehcache缓存框架整合
mybatis二级缓存通过ehcache维护缓存数据。
5.1 分布缓存
将缓存数据数据进行分布式管理。
5.2 mybatis和ehcache思路
通过mybatis和ehcache框架进行整合,就可以把缓存数据的管理托管给ehcache。
在mybatis中提供一个cache接口,只要实现cache接口就可以把缓存数据灵活的管理起来。
mybatis中默认实现:
5.3 下载和ehcache整合的jar包
ehcache对cache接口的实现类:
5.4 配置ehcache.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>
5.5 整合测试
在mapper.xml添加ehcache配置:
<!-- 开启二级缓存 -->
<!-- 单位:毫秒 -->
<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>
6 二级缓存的应用场景
对查询频率高,变化频率低的数据建议使用二级缓存。
对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度,业务场景比如:耗时较高的统计分析sql、电话账单查询sql等。
实现方法如下:通过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,比如设置为30分钟、60分钟、24小时等,根据需求而定。
7 mybatis局限性
mybatis二级缓存对细粒度的数据级别的缓存实现不好,比如如下需求:对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次都能查询最新的商品信息,此时如果使用mybatis的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,因为mybaits的二级缓存区域以mapper为单位划分,当一个商品信息变化会将所有商品信息的缓存数据全部清空。解决此类问题需要在业务层根据需求对数据有针对性缓存。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# mybatis
# 查询缓存
# mybatis的一级缓存
# 缓存
# ehcache
# mybatis-plus报错Not Found TableInfoCache异常
# mybatis整合ehcache做三级缓存的实现方法
# 在Mybatis中使用自定义缓存ehcache的方法
# JavaWeb开发之Spring+SpringMVC+MyBatis+SpringSecurity+
# Mybatis添加Ehcache支持的方法
# MyBatis验证多级缓存及 Cache Aside 模式的应用小结
# 清空
# 设置为
# 查询结果
# 移除
# 数据结构
# 数据库查询
# 是一个
# 序列化
# 较高
# 每隔
# 就可以
# 中取
# 默认值
# 自己的
# 的是
# 运行环境
# 放在
# 正整数
# 都要
# 不需要
相关文章:
建站之星导航配置指南:自助建站与SEO优化全解析
早安海报制作网站推荐大全,企业早安海报怎么每天更换?
如何设置并定期更换建站之星安全管理员密码?
建站之星上传入口如何快速找到?
免费ppt制作网站,有没有值得推荐的免费PPT网站?
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
如何在阿里云ECS服务器部署织梦CMS网站?
如何选择域名并搭建高效网站?
建站之星CMS五站合一模板配置与SEO优化指南
建站主机空间推荐 高性价比配置与快速部署方案解析
如何获取免费开源的自助建站系统源码?
建站之星北京办公室:智能建站系统与小程序生成方案解析
潍坊网站制作公司有哪些,潍坊哪家招聘网站好?
网站设计制作公司地址,网站建设比较好的公司都有哪些?
怎么将XML数据可视化 D3.js加载XML
建站一年半SEO优化实战指南:核心词挖掘与长尾流量提升策略
临沂网站制作企业,临沂第三中学官方网站?
制作网站的软件免费下载,免费制作app哪个平台好?
建站之星如何快速更换网站模板?
Python lxml的etree和ElementTree有什么区别
武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?
建站之星图片链接生成指南:自助建站与智能设计教程
打鱼网站制作软件,波克捕鱼官方号怎么注册?
如何快速辨别茅台真假?关键步骤解析
网站企业制作流程,用什么语言做企业网站比较好?
如何登录建站主机?访问步骤全解析
,石家庄四十八中学官网?
长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?
C++如何编写函数模板?(泛型编程入门)
SAX解析器是什么,它与DOM在处理大型XML文件时有何不同?
如何在IIS中新建站点并解决端口绑定冲突?
孙琪峥织梦建站教程如何优化数据库安全?
如何高效利用亚马逊云主机搭建企业网站?
设计网站制作公司有哪些,制作网页教程?
用v-html解决Vue.js渲染中html标签不被解析的问题
如何快速搭建高效WAP手机网站?
如何通过可视化优化提升建站效果?
广州网站建站公司选择指南:建站流程与SEO优化关键词解析
建站主机选购指南:核心配置与性价比推荐解析
如何在新浪SAE免费搭建个人博客?
nginx修改上传文件大小限制的方法
深圳网站制作的公司有哪些,dido官方网站?
儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?
北京的网站制作公司有哪些,哪个视频网站最好?
建站之星下载版如何获取与安装?
定制建站方案优化指南:企业官网开发与建站费用解析
如何快速搭建高效香港服务器网站?
如何在Golang中使用encoding/gob序列化对象_存储和传输数据
网站建设制作、微信公众号,公明人民医院怎么在网上预约?
如何确保FTP站点访问权限与数据传输安全?
*请认真填写需求信息,我们会在24小时内与您取得联系。