MyBatis学习——MyBatis与Ehcache缓存插件整合

一、为什么不使用MyBatis的二级缓存?

MyBatis的二级缓存就如同它的一级缓存一样,可应用的范围太狭隘了。MyBatis的每一个二级缓存都对应一个namespace,即每一个namespace下的二级缓存都是相对独立的,互不影响。而且因为增删改会改变数据库表里的数据,所以缓存会自动刷新。从这两点可以总结,在实际的开发中,理想的使用二级缓存的环境是:

1.系统下所有的操作都是单表操作;

2.使用查询的业务场景要远远的多于增删改场景。

以上两点对于实际开发来说都是几乎不可能的,原因如下:

1.业务场景的复杂性决定了多数的数据库表操作都是多表关联操作,即使是简单的OA系统,查询用户也要关联到部门信息。

2.我们在实际的开发中,都会使用generator来生成mapper文件,所以每一个表都会有一一对应的namespace。但是业务场景的复杂性决定了我们很难不在其他的namespace下操作当前的表,特指多表操作,包括查询、增加、修改。以电商平台为例,用户购买订单需要扣除账户余额,我们在订单Mapper下关联操作用户账户表时,会导致账户mapper的二级缓存无法及时刷新,从而导致系统读取到的账户信息时订单扣款前的数据(这是因为每一个namespace都是独立的)。

3.使用cache-ref共享同一个namespace下的二级缓存?那缓存的应用范围就太过狭隘了。

4.MyBatis是做数据库交互的,所谓术业有专攻,MyBatis没有精力也没有理由去做一个强大的缓存,它只需提供一个接口,规定缓存的规范就可以了。

二、MyBatis整合Ehcache

MyBatis提供了缓存的接口Cache,第三方缓存插件只需要实现这个接口就可以了。强大的缓存插件如Redis、membercache、

Ehcache等等为我们提供了丰富的缓存服务,这里介绍一下MyBatis怎么整合Ehcache

1.jar包准备


Ehcache需要用到三个jar包:

Maven依赖是:

<!-- mybatis整合Ehcache -->
		<dependency>
			<groupId>slf4j-api</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.7.19</version>
		</dependency>
		
		<dependency>
	      <groupId>net.sf.ehcache</groupId>
	      <artifactId>ehcache-core</artifactId>
	      <version>2.6.11</version>
	    </dependency>
		<!-- Encache适配包 -->
		<dependency>
		    <groupId>org.mybatis.caches</groupId>
		    <artifactId>mybatis-ehcache</artifactId>
		    <version>1.0.3</version>
		</dependency>
2.编写Ehcache.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>  
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">  
    <diskStore path="F:/ehcache" />  
    <!-- DefaultCache setting. -->  
     <defaultCache  
            maxElementsInMemory="1000"  
            eternal="false"  
            timeToIdleSeconds="120"  
            timeToLiveSeconds="120"  
            maxElementsOnDisk="1000000"  
            overflowToDisk="true"   
            memoryStoreEvictionPolicy="LRU">  
              
    </defaultCache>  
  
    <!-- Special objects setting. -->  
  
    <cache name="myCache"  
           maxElementsOnDisk="20000"  
           maxElementsInMemory="2000"  
           eternal="true"  
           overflowToDisk="true"  
           diskPersistent="true"/>  
  
</ehcache>
标签解释如下:

<diskStore>当内存缓存中对象数量超过maxElementsInMemory时,将缓存对象写到磁盘缓存中(需对象实现序列化接口)  
<diskStore path="">
用来配置磁盘缓存使用的物理路径,Ehcache磁盘缓存使用的文件后缀名是*.data和*.index  
name
缓存名称,cache的唯一标识(ehcache会把这个cache放到HashMap里)  
maxElementsOnDisk
磁盘缓存中最多可以存放的元素数量,0表示无穷大  
maxElementsInMemory
内存缓存中最多可以存放的元素数量,若放入Cache中的元素超过这个数值,则有以下两种情况  
                     1)若overflowToDisk=true,则会将Cache中多出的元素放入磁盘文件中  
                     2)若overflowToDisk=false,则根据memoryStoreEvictionPolicy策略替换Cache中原有的元素  
eternal
缓存中对象是否永久有效,即是否永驻内存,true时将忽略timeToIdleSeconds和timeToLiveSeconds  
timeToIdleSeconds
缓存数据在失效前的允许闲置时间(单位:秒),仅当eternal=false时使用,默认值是0表示可闲置时间无穷大,此为可选属性  
                     即访问这个cache中元素的最大间隔时间,若超过这个时间没有访问此Cache中的某个元素,那么此元素将被从Cache中清除  
timeToLiveSeconds
缓存数据在失效前的允许存活时间(单位:秒),仅当eternal=false时使用,默认值是0表示可存活时间无穷大  
                     即Cache中的某元素从创建到清楚的生存时间,也就是说从创建开始计时,当超过这个时间时,此元素将从Cache中清除  
overflowToDisk
内存不足时,是否启用磁盘缓存(即内存中对象数量达到maxElementsInMemory时,Ehcache会将对象写到磁盘中)  
                     会根据标签中path值查找对应的属性值,写入磁盘的文件会放在path文件夹下,文件的名称是cache的名称,后缀名是data  
diskPersistent
是否持久化磁盘缓存,当这个属性的值为true时,系统在初始化时会在磁盘中查找文件名为cache名称,后缀名为index的文件  
                     这个文件中存放了已经持久化在磁盘中的cache的index,找到后会把cache加载到内存  
                     要想把cache真正持久化到磁盘,写程序时注意执行net.sf.ehcache.Cache.put(Element element)后要调用flush()方法  
diskExpiryThreadIntervalSeconds
磁盘缓存的清理线程运行间隔,默认是120秒  
diskSpoolBufferSizeMB
设置DiskStore(磁盘缓存)的缓存区大小,默认是30MB  
memoryStoreEvictionPolicy
内存存储与释放策略,即达到maxElementsInMemory限制时,Ehcache会根据指定策略清理内存  
                                 共有三种策略,分别为LRU(最近最少使用)、LFU(最常用的)、FIFO(先进先出)  


3.mybatis启用Ehcache

<!-- 使用Encache -->
    	<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
关联namespace下的缓存使用cache-ref:

<!-- 引用指定namespace下的缓存 -->
    	<cache-ref namespace="com.xuyong.dao.UserMapper"/>
到此,MyBati与Ehcache的整合就结束了,附上Ehcache详细解读的博文链接:

Ehcache详细解读

关于Ehcache与Spring的整合,以及如何在业务开发中使用Ehcache,在这篇博客里有介绍:ehcache入门基础示例

猜你喜欢

转载自blog.csdn.net/postersxu/article/details/79079327