关于Spring中Ehcache缓存在MyBatis上应用的二三事

  提到初次接触到Ehcache缓存的时候还有些惭愧的说,为什么么这么讲呢?因为穷啦,租不起太好的服务器,为了节省性能,开始接触了Ehcache缓存。
  说道Ehcache,咱先来段度娘语录:【Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。】,嗯简单来说就是一个Java的二级缓存框架啦。可能会有人问缓存是什么,有什么用啊。我们举个例子吧,日语雪怎么读呀,我们通过查日语字典得知罗马音是yuki,可是我们下次再遇到的话就还要再查一遍我们的大字典,为了省事,我想了一个好办法,反正我脑子笨经常要雪的读音,干脆我把yuki写在我的手背上吧,想不起来了就看手背一下就知道了,不用在查字典的说。有人会说,这还用你你这个死宅说,我还能写在我的脑子里呢。嘛嘛,消消气,大概是这个意思啦,数据库每次查询都会消耗一定的性能,为了节省性能,我们可以吧第一次的查询结果写在电脑内存中,直接从内存中取出储存的结果,内存的速度大家都懂的吧(怎么突然想到了塑料内存条那个虐心动画去了),如果某些数据库数据是我们经常查询并且很少更新修改删除的话,实在是用缓存再适合不过了~


  先说说Ehcache框架的好处吧,首先是简单啦,使用简单,广收人心。其次啦是二级缓存的说,如果内存中装的数据超过了预设最大值,该框架支持把多余数据的暂且写在硬盘中。还有就是可以通过RMI、可插入API等方式进行分布式缓存等啦。至于缺点,我就暂且摘录大大们的原话啦, 1、使用磁盘Cache的时候非常占用磁盘空间:这是因为DiskCache的算法简单,该算法简单也导致Cache的效率非常高。它只是对元素直接追加存储。因此搜索元素的时候非常的快。如果使用DiskCache的,在很频繁的应用中,很快磁盘会满。2、 不能保证数据的安全:当突然kill掉java的时候,可能会产生冲突,EhCache的解决方法是如果文件冲突了,则重建cache。这对于Cache数据需要保存的时候可能不利。当然,Cache只是简单的加速,而不能保证数据的安全。如果想保证数据的存储安全,可以使用Bekeley DB Java Edition版本。这是个嵌入式数据库。可以确保存储安全和空间的利用率。
  本次的重点是说说Ehcache缓存怎么与Spring以及MyBaties结合。网上虽然有很多教程,但很多都不能成功启用的说,这里来说说我们的实现方法吧。首先我们要在maven中加上相关jar包(此步为maven的配置方式),我们需要在pom.xml中加上

       <dependency>
		    <groupId>org.mybatis</groupId>
			<artifactId>mybatis-ehcache</artifactId>
			<version>1.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.ehcache</groupId>
			<artifactId>ehcache</artifactId>
			<version>3.0.0.m3</version>
		</dependency>

然后需要我们要在spring-mybatis.xml的同级目录下建立一个ehcache.xml文件,并在里写入

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
	updateCheck="false">
	<diskStore path="java.io.tmpdir" />
	<defaultCache eternal="false" maxElementsInMemory="10000"
		overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
		timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU" />
	<cache name="myCache" eternal="false" maxElementsInMemory="10000"
		overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
		timeToLiveSeconds="300" memoryStoreEvictionPolicy="LRU" />
</ehcache>

我们来说说其中的含意吧
name:缓存名称。
maxElementsInMemory:缓存最大个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
maxElementsOnDisk:硬盘最大缓存个数。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
  顺便说一下,defaultCache是默认配置策略。ehcache.xml文件配置好之后我们就可以为我们Spring添加Bean啦。我们需要把MyBatis的chache配置为Ehcache,则需要在我们的spring-mybatis.xml中添加如下Bean。

	<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:ehcache.xml" />
    </bean>

  接下来就是我们在MyBatis上的配置了,在我们需要进行缓存的Mapping中添加如下配置。

 <cache type="org.mybatis.caches.ehcache.LoggingEhcache" >  
    <property name="timeToIdleSeconds" value="0"/>
    <property name="timeToLiveSeconds" value="0"/>
    <property name="maxEntriesLocalHeap" value="1000"/>  
    <property name="maxEntriesLocalDisk" value="10000000"/>  
    <property name="memoryStoreEvictionPolicy" value="LRU"/>  
  </cache>

  每一部分的意思结合之前的大概都能看懂了吧~这样我们就可以为我们的MyBatis使用Ehcache缓存了。值得注意的是,查询出来的对象不要直接进行修改,否则会直接导致缓存的数据被改变,当然我们也可以利用这点来刷新缓存中被改变数据,举个例子,如果我们通过Mapper查询用户信息,查出了出结果并返回一个叫usera的对象,如多我们直接对usera的属性进行了修改,会导致缓存中的数据也被改变,我们可以再声明个新对象,再对新对象进行修改。
  如果有错误,请一定要指出来哇~

发表评论

电子邮件地址不会被公开。 必填项已用*标注