mybatis的文件系统机制(二级缓存二级缓存和更新缓存)和mybatis结合ehcache转载

原创
小哥 3年前 (2022-10-28) 阅读数 6 #大杂烩

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
版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除