SpringMVC+mybatis+maven+Ehcache缓存实现

所谓缓存,就是将程序或系统经常要调用的对象存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。

缓存主要可分为二大类: 

一、通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式;  

二、内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查.

一、EhCache缓存系统简介

EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,是 Hibernate 中默认的 CacheProvider。

EhCache 应用架构图,下图是 EhCache 在应用程序中的位置:

  EhCache 的主要特性有: 

    1. 快速、精干;

    2. 简单;

    3. 多种缓存策略;

    4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题;

    5. 缓存数据会在虚拟机重启的过程中写入磁盘;

    6. 可以通过 RMI、可插入 API 等方式进行分布式缓存;

    7. 具有缓存和缓存管理器的侦听接口;

    8. 支持多缓存管理器实例,以及一个实例的多个缓存区域;

    9. 提供 Hibernate 的缓存实现;

二、maven添加Ehcache核心包 

在pom.xml配置文件里,添加

  <!--ehcache 相关包 -->
   <dependency>
       <groupId>net.sf.ehcache</groupId>
       <artifactId>ehcache</artifactId>
       <version>2.7.5</version>
   </dependency>
   <dependency>
       <groupId>com.googlecode.ehcache-spring-annotations</groupId>
       <artifactId>ehcache-spring-annotations</artifactId>
       <version>1.2.0</version>
   </dependency>

三、添加配置文件

在资源文件夹下(通常是src/main/resources/META-INF) 添加 applicationContext-ehcache.xmlehcache.xml

1、applicationContext-ehcache.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:c="http://www.springframework.org/schema/c" 
xmlns:cache="http://www.springframework.org/schema/cache" xmlns:context="http://www.springframework.org/schema/context" 
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" 
xmlns:lang="http://www.springframework.org/schema/lang" xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:p="http://www.springframework.org/schema/p" xmlns:task="http://www.springframework.org/schema/task" 
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- 开启spring缓存 -->
    <cache:annotation-driven cache-manager="cacheManager" />
    <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:META-INF/ehcache.xml"/>
    </bean>
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="cacheManagerFactory"/>
    </bean>

</beans>

  这里是开启spring缓存   

2、ehcache.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
 monitoring="autodetect" dynamicConfig="true">

    <diskStore path="${java.io.tmpdir}/${system.project_name}/cache" />
    <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" 
          maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
    <cache name="baseCache" maxElementsInMemory="200" maxElementsOnDisk="1000" eternal="false" overflowToDisk="true" diskSpoolBufferSizeMB="20"
       timeToIdleSeconds="300" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU" />

</ehcache>

  这里是添加缓存策略

说明:

   1、java.io.tmpdir 所指地址:   

 操作系统不同 这个系统属性所表示的目录也不同
On Windows: java.io.tmpdir:[C:\DOCUME~1\joshua\LOCALS~1\Temp\]

On Solaris: java.io.tmpdir:[/var/tmp/]

On Linux: java.io.tmpdir: [/tmp]

On Mac OS X: java.io.tmpdir: [/tmp]

    The default temporary-file directory is specified by the system property java.io.tmpdir. On UNIX systems the default value of this property is typically "/tmp" or "/var/tmp"; on Microsoft Windows systems it is typically "c:\temp". A different value may be given to this system property when the Java virtual machine is invoked, but programmatic changes to this property are not guaranteed to have any effect upon the the temporary directory used by this method.

To specify the java.io.tmpdir System property, you can invoke the JVM as follows:

java -Djava.io.tmpdir=/path/to/tmpdir

By default this value should come from the TMP environment variable on Windows systems

2、数据含义

    name:Cache的唯一标识
    maxElementsInMemory:内存中最大缓存对象数
    maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大
    eternal:Element是否永久有效,一但设置了,timeout将不起作用
    overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中
    timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大
    timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,默认是0.,也就是element存活时间无穷大  
    diskPersistent:是否缓存虚拟机重启期数据  
    diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒
    diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区
    memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)
  或是LFU(较少使用)

四、DAO层做配置

    import org.springframework.cache.CacheManager;
  import org.springframework.cache.annotation.Cacheable;
    .....        
  @TriggersRemove(cacheName="baseCache",removeAll=true)
    public Entity save(Entity entity) throws CrudException {
        return entity;
    }

    @TriggersRemove(cacheName="baseCache",removeAll=true)
    public Entity update(Entity entity) throws CrudException {
        return entity;
    }

    @TriggersRemove(cacheName="baseCache",removeAll=true)
    public void del(Entity entity) throws CrudException {
            }

    @Cacheable(value="baseCache", key = "'findAll'")    
    public List<Entity> findAll() throws SearchException {
        return list;
    }

@Cacheable(value="baseCache", key = "'findAll'")

这个注解就是做到缓存数据,cacheName对应ehcache.xml 中配置

 @TriggersRemove(cacheName="baseCache",removeAll=true)

这个注解的作用就是当数据发生变化的时候清除缓存,做到数据同步

扩展:@Cacheable可以指定三个属性,value、key和condition。

1、@Cacheable("cache1")、@Cacheable({"cache1", "cache2"})//Cache是发生在cache1和cache2上的

    value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。

2、@Cacheable(value="users", key="#user.id")、@Cacheable(value="users", key="#p0")

    key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。我们这里先来看看自定义策略,自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性

  3、@Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")

有的时候我们可能并不希望缓存一个方法所有的返回结果。通过condition属性可以实现这一功能。condition属性默认为空,表示将缓存所有的调用情形。其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。以上下示例表示只有当user的id为偶数时才会进行缓存。

  4、@CachePut("users")

    在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

       @CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟@Cacheable是一样的。

  5、@CacheEvict(value="users", allEntries=true)

  allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。

  6、@CacheEvict(value="users", beforeInvocation=true)

    清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。

  7、@Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),

         @CacheEvict(value = "cache3", allEntries = true) })

public User find(Integer id) {

return null;

     }

   @Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。

如何知道有没生效:查看sql执行日志

参考:

http://www.blogjava.net/zzzlyr/articles/343234.html

http://blog.goyello.com/2010/07/29/quick-start-with-ehcache-annotations-for-spring/

http://haohaoxuexi.iteye.com/blog/2123030

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏服务端技术杂谈

从org.springframework.dao.DuplicateKeyException说起

通常在dao层将所有异常转嫁到Spring的RuntimeException体系(org.springframework.dao.DataAccessExcep...

1384
来自专栏技术/开源

进阶篇:以IL为剑,直指async/await

接上篇:30分钟?不需要,轻松读懂IL,这篇主要从IL入手来理解async/await的工作原理。 先简单介绍下async/await,这是.net 4.5引...

21410
来自专栏云瓣

JS 异步系列 —— Promise 札记

843
来自专栏加米谷大数据

Hive的数据类型

本文介绍hive的数据类型,数据模型以及文件存储格式。这些知识大家可以类比关系数据库的相关知识。

932
来自专栏吴伟祥

EhCache缓存工具类 原

参考:https://blog.csdn.net/qq_34531925/article/details/79134903

693
来自专栏芋道源码1024

数据库中间件 MyCAT源码分析——跨库两表Join

1. 概述 2. 主流程 3. ShareJoin 3.1 JoinParser 3.2 ShareJoin.processSQL(...) 3.3 Batc...

6708
来自专栏魂祭心

原 结合源码分析 setTimeout /

2896
来自专栏张善友的专栏

Spacebuilder在Mono上运行修改备忘

Spacebuilder 是一个asp.net mvc3项目,使用到了Combres,Combres依赖于dotless,然后在Spacebuilder的项目没...

1936
来自专栏PPV课数据科学社区

【学习】七天搞定SAS(五):数据操作与合并

数据集操作永远是逃不掉的问题,最简单的就是两个数据集的合并——当然不是简简单单的行列添加,按照某一主键或者某些主键合并才是最常用的。在SAS中,要熟悉的就是SE...

30611
来自专栏MasiMaro 的技术博文

windows 多任务与进程

多任务的本质就是并行计算,它能够利用至少2处理器相互协调,同时计算同一个任务的不同部分,从而提高求解速度,或者求解单机无法求解的大规模问题。以前的分布式计算正是...

814

扫码关注云+社区