您的位置:首页 > 其它

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

2018-01-16 22:14 288 查看
一、为什么不使用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入门基础示例
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: