我们先把sqlSession3部分注释掉来测试一下二级缓存的结果:
当我们把sqlSession3部分加上后,再测试一下二级缓存结果:
到这里,就明白了mybatis中二级缓存的执行原理
mybatis中还可以配置userCache和flushCache等配置项,userCache是用来设置是否禁用二级缓存的,在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。这种情况是针对每次查询都需要最新的数据sql,要设置成useCache=false,禁用二级缓存,直接从数据库中获取。
属性,默认情况下为true,即刷新缓存,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读。一般下执行完commit操作都需要刷新缓存,flushCache=true表示刷新缓存,这样可以避免数据库脏读。 一般我们不用设置,默认即可,这里只是提一下。
问题:我们需要将实体类序列化,否则就会报错
开启了二级缓存后,还需要将要缓存的pojo实现Serializable接口,为了将缓存数据取出执行反序列化操作,因为二级缓存数据存储介质多种多样,不一定只存在内存中,有可能存在硬盘中,如果我们要再取这个缓存的话,就需要反序列化了。所以建议mybatis中的pojo都去实现Serializable接口。下面以User为例截个图:
- 只要开启了二级缓存,在同一个Mapper下就有效
-
所有的数据都会先放在一级缓存中
-
只有当前会话提交,或者关闭的时候,才会提交到二级缓存中
Ehcache是一种广泛使用的开源Java分布式缓存框架。
回想一下上一节的内容,对某一命名空间的语句,只会使用该命名空间的缓存进行缓存或刷新。 但你可能会想要在多个命名空间*享相同的缓存配置和实例。要实现这种需求,你可以使用 cache-ref 元素来引用另一个缓存。
上面的部分主要总结了一下mybatis中二级缓存的使用,但是mybatis中默认自带的二级缓存有个弊端,即无法实现分布式缓存,什么意思呢?就是说缓存的数据在自己的服务器上,假设现在有两个服务器A和B,用户访问的时候访问了A服务器,查询后的缓存就会放在A服务器上,假设现在有个用户访问的是B服务器,那么他在B服务器上就无法获取刚刚那个缓存,如下图所示:
所以我们为了解决这个问题,就得找一个分布式的缓存,专门用来存储缓存数据的,这样不同的服务器要缓存数据都往它那里存,取缓存数据也从它那里取,如下图所示:
这样就能解决上面所说的问题,为了提高系统并发性能、我们一般对系统进行上面这种分布式部署(集群部署方式),所以要使用分布式缓存对缓存数据进行集中管理。但是mybatis无法实现分布式缓存,需要和其它分布式缓存框架进行整合,这里主要介绍ehcache。
上文一开始提到过,mybatis提供了一个cache接口,如果要实现自己的缓存逻辑,实现cache接口开发即可。mybatis本身默认实现了一个,但是这个缓存的实现无法实现分布式缓存,所以我们要自己来实现。ehcache分布式缓存就可以,mybatis提供了一个针对cache接口的ehcache实现类,这个类在mybatis和ehcache的整合包中。所以首先我们需要导入整合包(点我下载)。
我们将该类的完全限定名写到type属性中即可,如下:
OK,配置完成,现在mybatis就会自动去执行这个ehcache实现类了,就不会使用自己默认的二级缓存了,但是使用ehcache还有一个缓存配置别忘了,在classpath下新建一个ehcache.xml文件:
编写ehcache.xml文件,如果在 加载时 未找到 /ehcache.xml 资源或出现问题,则将使用默认配置。
diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位 defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策 eternal:对象是否永久有效,一但设置了,timeout将不起作用。 timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当 eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。 timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建 时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存 认是30MB。每个Cache都应该有自己的一个缓冲区。 会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先 出)或是LFU(较少使用)。 clearOnFlush:内存数量最大时是否清除。 FIFO(先进先出)、LFU(最少访问次数)。 LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以 来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。 LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容 量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的,一个游戏开发收藏夹~
如果图片长时间未显示,请使用Chrome内核浏览器。