首页 > 编程知识 正文

数据库缓存机制,java缓存有哪些

时间:2023-05-05 02:24:26 阅读:32560 作者:597

本文主要介绍MyBatis精彩缓存机制的设计原理,并向读者概述MyBatis缓存机制。 然后,我们将讨论每个缓存机制的各个方面。

MyBatis将数据缓存设计为两级结构,分为主缓存和辅助缓存。

一级缓存是会话级缓存,位于表示单个数据库会话的SqlSession对象中,也称为本地缓存。 一级缓存是MyBatis内部实现的特性,用户无法配置。 默认情况下自动支持的缓存,用户无权对其进行自定义(但这也不是绝对的,可以开发和修改插件)。

基于PerpetualCache的HashMap本地缓存。 l1缓存的范围是sqlSession,如果sqlSession被flush或close,则当前sqlSession中的所有缓存都将为空。

二级缓存是APP的APP应用程序级缓存,其生命周期与APP声明周期相同。 也就是说,它适用于整个APP。

与l1缓存机制类似,默认情况下也是使用PerpetualCache的HashMap存储,但l2缓存的范围是映射器(namespace )。

一级高速缓存

在举例之前,让我们先看看一级缓存的工作原理。

第一次在程序中启动用户id1的用户信息查询时,如果不首先搜索缓存中是否存在id1的用户信息,则在获得访问数据库查询用户信息的用户信息后,将用户信息作为主缓存

第二次启动用户id为1的查询,首先去查找缓存中是否有id为1的用户信息,如果在缓存中,则直接从缓存中检索相关数据。

在sqlsession中执行commit操作(添加、删除、修改)时,将清除sqlsession的主缓存,确保缓存中的信息是最新的数据,从而避免脏读。

一级缓存测试

默认情况下,mybatis支持l1缓存,不需要在配置文件中进行设置; 看看一级缓存的测试代码。

从执行结果可以看出:

第一个查询发出了sql语句,但第二个查询直接从主缓存检索数据,因此没有发出第二个查询。

但是,当您将mybatis与Spring集成时,事务由服务控制。

一个服务包含对许多mapper方法的调用。 如果执行两次服务调用并查询同一用户的信息,则不会进入主缓存。 第一个Service方法执行完成后,无法调用主缓存,因为该方法的sqlSession为空。

辅助缓存

与一级缓存的区别在于,必须手动打开二级缓存。 首先,在打开l2缓存之前测试一下效果。

运行上面的代码可以获得以下结果:

从上面的结果可以看出,在我们没有打开的情况下,mybatis和数据库有两次交互的过程。 也就是说,默认情况下,mybatis的辅助缓存处于关闭状态,并且必须手动设置。

打开l2缓存

(1)打开l2缓存的总开关(将以下内容添加到核心配置文件SqlMapConfig.xml中)。

将启用缓存设置为true

)2)在地图文件中,添加以下内容,打开l2缓存:

实现序列化

l2缓存的数据不一定存储在存储器中,其存储介质多种多样,需要对缓存的对象进行序列化。

如果该类中存在父类,则还必须序列化父类。

禁用l2缓存

如果在此语句中设置userCache=false,将禁用当前select语句的辅助缓存。 也就是说,每次查询都会查询数据库,缺省情况下为true。 也就是说,此语句使用辅助缓存。

刷新l2高速缓存

请注意,如果使用次缓存,则必须使用两个不同的会话,并且只有在提交第一个缓存时才能使用次缓存

自定义缓存

EhCache是一个纯Java流程缓存框架,具有快速、精细等特点,是Hibernate的默认EhCache提供程序。

MyBatis定义了Cache接口,以便我们可以定制和扩展。

步骤:

)1)部署ehcache软件包以及集成软件包、日志软件包

(2)创建ehcache.xml配置文件;3 )配置cache标记

如果命名空间共享相同的缓存配置和实例。 可以使用cache-ref元素引用其他缓存。

缓存相关属性

(1)eviction=“FIFO”:缓存回收策略:• 默认的是 LRU。

LRU – 最近最少使用的:移除最长时间不被使用的对象。

FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

(2)flushInterval:刷新间隔,单位毫秒

默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新

(3)size:引用数目,正整数

代表缓存最多可以存储多少个对象,太大容易导致内存溢出

(4)readOnly:只读,true/false

true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。

false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是 false。

缓存相关设置

(1)全局setting的cacheEnable:

配置二级缓存的开关。一级缓存一直是打开的。

(2)select标签的useCache属性:

配置这个select是否使用二级缓存。一级缓存一直是使用的

(3)sql标签的flushCache属性:

增删改默认flushCache=true。sql执行以后,会同时清空一级和二级缓存。

查询默认flushCache=false。

(4)sqlSession.clearCache():

只是用来清除一级缓存。

(5)当在某一个作用域 (一级缓存Session/二级缓存Namespaces) 进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。

总结

二级缓存与一级缓存区别,二级缓存的范围更大,多个sqlSession可以共享一个UserMapper的二级缓存区域。UserMapper有一个二级缓存区域(按namespace分) ,其它mapper也有自己的二级缓存区域(按namespace分)。每一个namespace的mapper都有一个二缓存区域,两个mapper的namespace如果相同,这两个mapper执行sql查询到数据将存在相同 的二级缓存区域中。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。