springboot整合ehcache使用
其实本地缓存的解决方案也有很多种,像Ehcache,GuavaCache,JCache等目前Ehcache 是现在最流行的纯Java开源缓存框架,配置简单、结构清晰、功能强大.在使用需要缓存时可以使用.使用起来简单方便.支持多种缓存策略.
详细介绍: https://www.iteye.com/blog/raychase-1545906
ehcache和redis的区别
ehcache直接在jvm虚拟机中缓存,速度快,效率高;但是缓存共享麻烦,集群分布式应用不方便。
redis是通过socket访问到缓存服务,效率比ecache低,比数据库要快很多,处理集群和分布式缓存方便,有成熟的方案。
如果是单个应用或者对缓存访问要求很高的应用,用ehcache。
如果是大型系统,存在缓存共享、分布式部署、缓存内容很大的,建议用redis。
补充下:ehcache也有缓存共享方案,不过是通过RMI或者Jgroup多播方式进行广播缓存通知更新,缓存共享复杂,维护不方便;简单的共享可以,但是涉及到缓存恢复,大数据缓存,则不合适。
思路:
springboot+ mybatis+ mysql+ehcache
将mysql中的数据缓存,第一查询从数据库查询,随后放入缓存,下次就不从数据库中取了.
项目分层:
pom依赖
<!--引用cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
先新建ehcache.xml配置文件
直接新建文件就行,后期会在配置类中引入
<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="testEhCache">
<defaultCache
name="defaultCa"
eternal="false"
maxElementsInMemory="900"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LRU"/>
<!-- 可以设置多种策略的缓存方式 -->
<cache
name="myCache"
eternal="false"
maxElementsInMemory="200"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LRU"/>
<cache
name="myCache22"
eternal="false"
maxElementsInMemory="200"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LRU"/>
<!--
name:缓存名称,在使用的时候使用。
maxElementsInMemory:缓存最大数目
maxElementsOnDisk:硬盘最大缓存个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
overflowToDisk:是否保存到磁盘,当系统当机时
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
memoryStoreEvictionPolicy:
Ehcache的三种清空策略;
FIFO,first in first out,这个是大家最熟的,先进先出。
LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
-->
</ehcache>
配置类
@Configuration
public class CacheConfig {
/**
* 这是一个工厂类,通过getObject()获取到真正的ehcacheCacheManager
* @return
*/
@Bean
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
EhCacheManagerFactoryBean factoryBean = new EhCacheManagerFactoryBean();
factoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
factoryBean.setShared(true);
return factoryBean;
}
/**
* 核心的缓存管理类,使用时直接注入即可
* @return
*/
@Bean
public EhCacheCacheManager ehCacheCacheManager() {
return new EhCacheCacheManager(ehCacheManagerFactoryBean().getObject());
}
}
创建put/get工具
springboot支持直接使用@Cacheable注解进行缓存,但是,我觉得用的不方便,还是使用工具类直观.所以就新建了一个工具类.
public class EhCacheUtil {
public static void setCache(EhCacheCacheManager cache,String key,Object object) {
//这里的 myCache是配置文件中的cache的name,是使用不同的缓存策略
Cache objectCache = cache.getCache("myCache");
objectCache.put(key,object);
}
public static Object getCache(EhCacheCacheManager cache,String key) {
Cache objectCache = cache.getCache("myCache");
if (objectCache.get(key)!=null && !objectCache.get(key).equals("")) {
return objectCache.get(key).get();
}
return null;
}
}
到此主要的配置已经完成了,只要将mybatis的环境建好即可.
dao和domain
这里就不放了,比较简单.以及application.properties中的数据库信息省略.
controller层
省略了service层,
@RestController
@Slf4j
public class UserController {
@Autowired
private EhCacheCacheManager ehCacheCache;
@Autowired
private UserDao userDao;
@GetMapping("/get")
public Object get() {
//先查询缓存
List<User> list =(List) EhCacheUtil.getCache(ehCacheCache, "userList");
if (list==null) {
log.info("这里去了数据库");
list = userDao.getAllUser();
//将list存入缓存
EhCacheUtil.setCache(ehCacheCache,"userList",list);
}
return list;
}
}
最后启动类
添加注解@EnableCaching
@SpringBootApplication
@MapperScan(value = {"com.jd.dao"})
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
测试一下
第一次访问:
缓存中没有去了数据库中查找.
第二次访问:
缓存中有了,没有去数据库.