缓存相关
内容大纲
- Spring的缓存注解
- Mybatis的一级、二级缓存
- Ehcache
源码
Spring 各种注解的源码,这里面service里面有keyGenerator的示例:
https://github.com/huangzhenshi/SSM_REDIS_ANNOTATION_DEMOSpring 整合ehcache源码 参考封装在公司PC里面的webTest 项目
C:\huangzs\缓存\缓存\Spring-ehcache_demos\webTest
Spring的缓存注解
引用博客
常用注解
- @Cacheable
- @CachePut
- @CacheEvict
- @CacheConfig
@Cacheable
- value
- key
- condition
value 类似于 班级,key类似于学号的概念,例如调用下面的方法,分别用id=1 id=2调用,
会在keys *中产生3个对象,必须要通过 value getById~keys 才找的到\xac\xed\x00\x05t\x00(com.lyz.user.service.UserServicegetById1这个键,再找到对应的真实缓存的值
getById~keys
\xac\xed\x00\x05t\x00(com.lyz.user.service.UserServicegetById2
\xac\xed\x00\x05t\x00(com.lyz.user.service.UserServicegetById1
value 设置两种方法
一个方法也可以指定多个value
key
可以通过SpringEL表达式 指定key
@Cacheable(value="getById", key="'getUserById'+#id")public String getUserById(Integer id) {return template.selectOne("com.lyz.user.mapper.UserMapper.getNameById", id);}可以通过配置重写keyGenerator的方法,如果重写了的话,同时也指定了key的话,优先取指定的key
condition
支持SpringEl表达式,可以添加 useCache 来动态 支持是否要从缓存中读取数据,还是直接通过数据库中即时的读取数据
@CachePut
- 每次执行的时候不会查看缓存,直接执行方法
- 执行完之后,会把最新的结果更新到缓存中
- 执行完 CachePut的时候,缓存中已经有了结果,如果其他方法的 value 和key值一定用cacheable的话,则可以获取到这个 缓存值
例如下面2个方法, value 和 key一样共享缓存的,如果更新过数据库要更新某个数据的缓存,可以调用第二个方法,同时下次执行第一个缓存方法的时候,会取到更新过后的结果。
@CacheEvict
清空一个或者多个缓存的 部分或者全部key的缓存
- 可以定点删除某个缓存下的 某个key的缓存
如下会删除 getUserById的缓存下 getUserById+参数 为key的缓存
删除getUserById的缓存中的所有key的缓存
@CacheEvict(value="getUserById" , allEntries=true)public String deleteCache(Integer id) {System.out.println("go go go ");return null;}删除多个缓存下的所有key的缓存
@CacheEvict(value={"getUserById","getAllUser"} , allEntries=true)public String deleteCache(Integer id) {System.out.println("go go go ");return null;}
@CacheConfig
- 类级别的缓存标志,所有的方法如果有 @cacheable 并且未指定 value的话都会默认继承
- 如果没有@Cacheable的方法,不会缓存
- 如果有@Cacheable的注解,但是指定了 value的话,以指定的value为实际的value
Mybatis的一级、二级缓存
- mybatis的一级缓存是默认开启的,但是只有在该方法是在事务开启的时候才有效,否则还是一个request当中重复读取的,重点注意
- mybatis 二级缓存需要配置 开启即可,但是mybatis的二级缓存是针对 mapper的文件的缓存,但是ehcache是方法级别的缓存,所以优先使用 ehcache
Ehcache
Ehcache特点
- JAVA写的非分布式缓存框架
- 支持缓存持久化
- 结合Spring的缓存注解可以实现方法级别的缓存和灵活的配置
引入spring中结合注解
Application.xml
<!-- 引入ehcache配置 start --><cache:annotation-driven cache-manager="cacheManager" /><bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"><property name="cacheManager" ref="ehcache"></property></bean><bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"><property name="configLocation" value="classpath:ehcache.xml"></property></bean><!-- 引入ehcache配置 end -->引入对应的ehcache.xml文件
然后就可以根据通用Spring 缓存注解一样使用了,注意 value要等于ehcache的 name
Ehcache.xml
- 配置 cache的name 对应,Spring 注解当中的 value,否则会报错,实现对一类 cacheTest类的缓存 根据key不同缓存
|
指定缓存文件持久化的路径
<!-- 指定一个文件目录,当EhCache把数据写到硬盘上时,将把数据写到这个文件目录下 --><diskStore path="C:/huangzs/缓存"/>maxElementsInMemory 最大缓存数
内存缓存中最多可以存放的元素数量,若放入Cache中的元素超过这个数值,则有以下两
种情况
1)若overflowToDisk=true,则会将Cache中多出的元素放入磁盘文件中
2)若overflowToDisk=false,则根据memoryStoreEvictionPolicy策略替换Cache中原有的元素memoryStoreEvictionPolicy
ehcache 中缓存的3 种清空策略:
- FIFO ,first in first out ,这个是大家最熟的,先进先出,不多讲了
- LFU , Less Frequently Used ,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存。
- LRU ,Least Recently Used ,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
LRU 和FIFO的区别是,最先进去的缓存对象如果后来被使用过,则时间戳会改变
- 标准可用的ehcache.xml 参考<?xml version="1.0" encoding="UTF-8"?><ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="ehcache.xsd"updateCheck="false"><!-- 指定一个文件目录,当EhCache把数据写到硬盘上时,将把数据写到这个文件目录下 --><diskStore path="C:/huangzs/缓存"/><defaultCachemaxElementsInMemory="10000"eternal="false"overflowToDisk="true"timeToIdleSeconds="10"timeToLiveSeconds="20"diskPersistent="false"diskExpiryThreadIntervalSeconds="120"/><cache name="cacheTest"maxElementsInMemory="1000"eternal="false"overflowToDisk="true"timeToIdleSeconds="1000"timeToLiveSeconds="2000"/><cache name="cacheTest3"maxElementsInMemory="10000"eternal="false"overflowToDisk="true"timeToIdleSeconds="1000"timeToLiveSeconds="2000"diskPersistent="false"diskExpiryThreadIntervalSeconds="120"/></ehcache>
Hibernate 一级、二级缓存
- hibernate的二级缓存是基于HQL或者 SQL的二级缓存
例如根据ID查询某个对象的时候,开启配置了二级缓存,就会从缓存中读取结果集。
参考这个对Bean进行缓存设置
- Ehcache 实战
E学E用利用的是hibernate的二级缓存 - 对地区类进行二级缓存@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)@Entity@Table(name = "region")public class Region implements Serializable {
ehcache.xml 里面的配置到这个Bean

