1 查询缓存
1.1 什么是查询缓存
mybatis提供查询缓存,减轻数据压力,提升数据库性能。
mybaits提供一级缓存和二级缓存。
一级缓存是SqlSession缓存级别。在操作数据库时,有必要进行构造。 sqlSession对象,则该对象中有一个。(内存区域)数据结构(HashMap)用于存储缓存数据。不同sqlSession缓存数据区域(HashMap)相互不受影响。
一级缓存的作用域相同SqlSession,在同一个版本中sqlSession在中执行两次相同的操作sql语句中,第一次执行时会将数据库中查询的数据写入缓存(内存),第二次从缓存中获取的数据将不再从数据库中查询,从而提高了查询效率。当一个sqlSession结束后该sqlSession中的一级缓存。Mybatis默认情况下,一级缓存处于打开状态。
二级高速缓存是mapper高速缓存级别,多个SqlSession以同样的方式操作Mapper的sql语句,多个SqlSession将有一个辅助缓存区,多个SqlSession可以共用二级缓存,二级高速缓存是跨SqlSession的。
二级高速缓存是多个SqlSession共享,其范围是mapper的同一个namespace,不同的sqlSession这两次处决是相同的。namespace下的sql语句且向sql传入的参数是相同的,即。最后的执行是一样的。sql语句中,第一次执行时会将数据库中查询的数据写入缓存(内存),第二次从缓存中获取的数据将不再从数据库中查询,从而提高了查询效率。Mybatis默认情况下,不需要打开任何二级缓存。setting全局参数配置为打开二级缓存。
如果缓存中有数据,则不必从数据库获取数据,从而极大地提高了系统性能。
1.2 一级缓存
1.2.1 一级缓存的工作原理
下图基于以下数据id查询用户的一级缓存图。
第一个查询用户id为1对于用户信息,首先查看缓存中是否有用户信息。id为1如果没有,则从数据库中查询用户信息。
获取用户信息,并将用户信息存储在一级缓存中。
如果sqlSession去执行commit操作(执行插入、更新、删除),为空SqlSession这样做的目的是将最新信息存储在缓存中并避免脏读。
第二查询用户id为1对于用户信息,首先查看缓存中是否有用户信息。id为1缓存中的用户信息直接从缓存中获取。
1.2.2 一级缓存测试
mybatis默认支持一级缓存,不需要在配置文件中配置。
按照上述一级缓存原则步骤进行测试。
@Test
public void testCache1() throws Exception{
SqlSessionsqlSession = sqlSessionFactory.openSession();//创建代理对象
UserMapperuserMapper = sqlSession.getMapper(UserMapper.class);
//下面的查询使用一个。SqlSession
//第一次发起请求,查询id为1的用户
Useruser1 = userMapper.findUserById(1);
System.out.println(user1);
// 如果sqlSession去执行commit操作(执行插入、更新、删除),为空SqlSession这样做的目的是将最新信息存储在缓存中并避免脏读。
//更新user1的信息
user1.setUsername("测试用户22");
userMapper.updateUser(user1);
//执行commit清空缓存的操作
sqlSession.commit();
//第二个请求,查询id为1的用户
Useruser2 = userMapper.findUserById(1);
System.out.println(user2);
sqlSession.close();
}
1.2.3 1级缓存应用程序
正式的开发是mybatis和spring集成开发、事务控制service中。
一个service该方法包括许多mapper方法调用。
service{
//开始执行,打开事务,创建。SqlSession对象
//第一次呼叫mapper的方法findUserById(1)
//第二个电话mapper的方法findUserById(1),从一级缓存中获取数据。
//aop控制 只要该方法结束,sqlSession关闭 sqlsession关闭后,数据结构将被销毁,缓存将被清除。
Service结束sqlsession关闭
}
如果执行两次service调用查询相同的用户信息时,不要去一级缓存,因为。Service方法结束,sqlSession如果关闭,则会清除一级缓存。
1.3 二级缓存
1.3.1 原理
首先开启mybatis二级缓存的。
sqlSession1查询用户的步骤id为1用户信息,查询会将查询数据存储在二级缓存中。
如果SqlSession3执行相同的操作 mapper下sql,执行commit提交,将其清空 mapper下的二级缓存区的数据。
sqlSession2查询用户的步骤id为1对于用户信息,请转到缓存以查看是否有数据,以及是否有直接来自缓存的数据。
二级缓存不同于一级缓存,二级缓存的范围更大、更多。sqlSession可以共享一个UserMapper二级缓存区的。数据类型仍为HashMap
UserMapper有一个辅助缓存区(按namespace分,如果namespace相同的二级缓存用于相同的缓存,而另一种则使用相同的二级缓存。mapper还有自己的二级缓存区(按下namespace分)。
每一个namespace的mapper两者都有两个缓存区,两个mapper的namespace如果相同,则两者mapper执行sql查询数据将存在于相同的二级缓存区中。
1.3.2 打开二级缓存
mybaits的二级高速缓存是mapper作用域级别,但在SqlMapConfig.xml设置二级缓存的主开关,还可以在特定的mapper.xml中打开二级缓存。
在核心配置文件中SqlMapConfig.xml中加入
描述
允许值
默认值
cacheEnabled
为这份档案下的所有人。cache 实施全域开放/关设置。
true false
true
在UserMapper.xml打开第二高速缓存,UserMapper.xml下的sql执行完成并存储在其缓存区(HashMap)。
1.3.3 调用pojo类实现序列化接口。
public class Userimplements Serializable {
//Serializable为将来的反序列化实现序列化。
二级缓存需要查询结果映射。pojo对象实现java.io.Serializable接口实现序列化和反序列化操作,请注意,如果有父类,则成员。pojo两者都需要实现序列化接口。
pojo类实现序列化接口。是为了将缓存数据取出执行反序列化操作,因为二级缓存数据存储介质多种多样,不一定在内存有可能是硬盘或者远程服务器。
1.3.4 测试方法
// 二级缓存测试
@Test
public void testCache2() throws Exception {
SqlSessionsqlSession1 = sqlSessionFactory.openSession();
SqlSessionsqlSession2 = sqlSessionFactory.openSession();
SqlSessionsqlSession3 = sqlSessionFactory.openSession();
// 创建代理对象
UserMapperuserMapper1 = sqlSession1.getMapper(UserMapper.class);
// 第一次发起请求,查询id为1的用户
Useruser1 = userMapper1.findUserById(1);
System.out.println(user1);
//在这里执行关机操作,威尔。sqlsession将中的数据写入二级缓存区。
sqlSession1.close();
//使用sqlSession3执行commit()操作
UserMapperuserMapper3 = sqlSession3.getMapper(UserMapper.class);
Useruser = userMapper3.findUserById(1);
user.setUsername("张明明");
userMapper3.updateUser(user);
//执行提交,为空UserMapper较低的二级高速缓存
sqlSession3.commit();
sqlSession3.close();
UserMapperuserMapper2 = sqlSession2.getMapper(UserMapper.class);
// 第二个请求,查询id为1的用户
Useruser2 = userMapper2.findUserById(1);
System.out.println(user2);
sqlSession2.close();
}
1.3.5 useCache配置为禁用二级缓存
在statement中设置useCache=false您可以禁用当前select语句的二级缓存,即E。发出每个查询。sql要进行查询,默认为。true,即该sql使用二级缓存。
摘要:每次查询都需要最新数据。sql,待定useCache=false,禁用二级缓存。
1.3.6 mybatis刷新缓存(即清空缓存)
在mapper的同一个namespace在,如果有其他insert、update、delete在操作数据之后,需要刷新缓存。如果未刷新缓存,则将发生脏读操作。
设置statement配置中的flushCache="true" 属性,默认情况下true也就是说,如果更改,则刷新缓存false它不会刷新。如果在使用高速缓存时手动修改数据库表中的查询数据,则会发生脏读。
如下:
摘要:基本完成commit操作需要刷新高速缓存,flushCache=true指示默认情况下刷新缓存为。true,我们不需要设置它,所以我们可以避免读取脏数据库。
1.3.7 Mybatis Cache参数
flushInterval(刷新间隔)可以设置为任何正整数,并且它们以毫秒的形式表示合理的时间段。不设置缺省值,即没有刷新间隔,只在调用该语句时刷新缓存。
size(引用的数量)可以设置为任何正整数,请记住您缓存的对象数量和运行环境中可用内存资源的数量。缺省值为1024。
readOnly可以设置(只读)属性true或false。只读缓存将缓存对象的相同实例返回给所有调用方。因此,不能修改这些对象。这提供了一种重要的性能优势。读写缓存返回缓存对象的副本(通过序列化)。这将较慢,但很安全,因此默认设置为。false。
以下示例:
此更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,结果对象或列表的数量。 512 个引用,并且返回的对象被视为只读。,因此,在不同线程中的调用方之间修改它们可能会导致冲突。可用的缩回策略包括, 默认的是 LRU:
1. LRU – 最近最少使用:删除未使用时间最长的对象。
2. FIFO – 先进先出:按对象进入缓存的顺序删除对象。
3. SOFT – 软引用:根据垃圾回收器状态和软引用规则删除对象。
4. WEAK – 弱引用:基于垃圾回收器状态和弱引用规则更主动地删除对象。
1.4 mybatis整合ehcache
ehcache是一个分布式缓存框架。
EhCache 是一个纯Java进程内缓存框架是一个广泛使用的开源框架。Java分布式缓存,具有快速、精简等特点。Hibernate中默认的CacheProvider。
1.4.1 分布缓存
为了提高系统的并发性,我们的系统进行分布式部署(集群部署)
不使用分布式缓存,缓存的数据分别存放在各个服务中,不方便系统开发。因此,使用分布式缓存来集中管理缓存数据。
mybatis分布式缓存无法实现,需要与其他分布式缓存框架集成。
1.4.2 整合方法(师傅不管融合谁,首先想到的是改变type接口)
mybatis提供了一种cache接口,如果您想实现自己的缓存逻辑,请实现cache界面开发就足够了。
mybatis和ehcache整合,mybatis和ehcache整合包中提供了一种cache接口的实现类。
1.4.3 第1步加入ehcache包
1.4.4 整合ehcache
配置mapper中cache中的type为ehcache对cache接口的实现类型。
缓存参数可以根据需要进行调整:
1.4.5 加入ehcache的简介
在classpath下配置ehcache.xml
物业说明:
diskStore:指定数据在磁盘上的存储位置。
defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用指定的管理策略
以下属性是必需的:
maxElementsInMemory - 在内存中缓存element最大数量
maxElementsOnDisk - 在磁盘上缓存element最大数量,若是0表示无穷大
eternal - 设置缓存elements它是否永远不会过期。如果true,则缓存的数据始终有效。false然后根据timeToIdleSeconds,timeToLiveSeconds判断
overflowToDisk- 设置内存缓存在溢出时是否会过期。element缓存到磁盘
以下属性是可选的:
timeToIdleSeconds - 当缓存在EhCache中数据之前和之后的时间timeToIdleSeconds属性时,此数据将被删除0,也就是说,空闲时间是无限的。
timeToLiveSeconds - 缓存element有效寿命的缺省值为0.,也就是element生存时间是无限的
diskSpoolBufferSizeMB 此参数设置DiskStore(磁盘缓存)的高速缓存大小.默认是30MB.每个Cache每个人都应该有自己的缓冲区。.
diskPersistent在VM重启时是否启用磁盘保存EhCache中的数据,默认为false。
diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认为120秒。每个120s,则相应的线程将执行一次。EhCache清理中的数据
memoryStoreEvictionPolicy - 当内存缓存达到其最大值时,会有一个新的element连接时,请移除缓存element战略。缺省值为LRU(最近最少使用),可选。LFU(最不常用)和FIFO(先进先出)
1.5 二次应用场景
对于多次访问的查询请求,以及用户对查询结果的实时性要求不高的情况,可以使用该功能。mybatis二级缓存技术减少了数据库访问,提高了访问速度,业务场景:耗时的统计分析。sql,电话账单查询sql等。
其实现如下:通过设置刷新间隔,。mybatis定期自动清除缓存,并根据数据更改频率设置缓存刷新间隔flushInterval,如SET30分钟、60分钟、24工作时间等,视需求而定。
1.6 二级缓存限制
mybatis二级缓存没有很好地实现细粒度的数据级缓存。为了同时缓存更多的数据,如:缓存商品信息,由于商品信息查询的访问量大,用户每次都需要查询最新的商品信息。如果在此时使用mybatis当一个商品发生变化时,的二级缓存不能只刷新一个商品的缓存信息,而不刷新其他商品的信息,因为mybaits的二级缓存区mapper作为一个单位划分,当一个商品信息发生变化时,所有商品信息的缓存数据都会被清除。解决此类问题需要根据需要在业务级别有针对性地缓存数据。需要三级缓存
————————————————
版权声明:本文是CSDN博主《双斜杠少年》的原文如下CC 4.0 BY-SA版权协议,转载请附上原始来源链接和本声明。
原始链接:https://blog.csdn.net/u012373815/article/details/47069223
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除