最近工做没有那么忙,有时间来写写东西。今年的系统分析师报名已经开始了,面对历年的真题,真的难以入笔,因此忽然对将来充满了担心,仍是得抓紧时间学习技术。javascript
同事推了一篇软文,看到了这个Ehcache,感受简单又好用,因此在本身这边也作个记录。java
先来谈谈什么是Ehcache缓存,咱们从实际场景出发,支撑一个系统最直接的东西就是数据库,针对数据库咱们最经常使用的操做就是查询。反复的查询数据库会致使数据库压力变大,传统的数据库查询效率就不高(网络、sql语句复杂),致使查询体验很差。尤为当咱们查询的语句仍是相似甚至重复的时候,这就是浪费资源了。那这个时候,缓存机制就变得颇有必要了。像咱们常用的实现缓存的方式大体有两种,一种是NoSQL数据库,好比Redis、MongoDB等,另外一种即是今天要提的缓存框架:Ehcache、Memcache等。web
引用官方的内容一句话定义:EhCache 是一个纯Java的进程内缓存框架,具备快速、精干等特色,是Hibernate中默认的CacheProvider。spring
下面就开始使用了:sql
<ehcache.version>2.6.10</ehcache.version>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>${ehcache.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- ehchace缓存管理器:ehcache缓存大对象 -->
<bean id="ehcacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<!-- 注入缓存配置文件的位置 -->
<property name="configLocation" value="classpath:ehcache.xml" />
</bean>
<!-- shiro缓存管理器:整合ehcache -->
<bean id="shrioCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- 注入ehcache的缓存管理器 -->
<property name="cacheManager" ref="ehcacheManager" />
</bean>
<!-- shiro安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 注入 Realm链接安全数据 -->
<property name="realm" ref="bosRealm"></property>
<!-- 注入shiro的缓存管理器 -->
<property name="cacheManager" ref="shiroCacheManager" />
</bean>
<!--经过配置的方式配置realm对象,这里参考 -->
<!-- <bean id="bosRealm" class="cn.itcast.bos.auth.realm.BosRealm"> 注入缓存具体对象的名字,该名字在ehcache.xml中配置的
<property name="authenticationCacheName" value="BosShiroCache"/> </bean> -->
@Component("bosRealm")
public class BosRealm extends AuthorizingRealm{
//注入缓存名称
@Value("BosShiroCache")//注入缓存具体对象的名字,该名字在ehcache.xml中配置的
public void setSuperAuthenticationCacheName(String authenticationCacheName){
super.setAuthenticationCacheName(authenticationCacheName);
}
}
<!-- 自定义缓存区域 -->
<cache name=" BosShiroCache " maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap" />
</cache>
默认的策略:
<!-- 硬盘缓存的临时路径 -->
<diskStore path="java.io.tmpdir" />
<!-- 默认的缓存区域的缓存策略 maxElementsInMemory:内存中最大容纳的元素数量 eternal:对象是否永生,默认是false
timeToIdleSeconds:发呆不用超过多长时间,over死掉 timeToLiveSeconds:活多久就死掉。 maxElementsOnDisk:硬盘上能存放多少元素
diskExpiryThreadIntervalSeconds:轮询的时间,检查的时间。 memoryStoreEvictionPolicy:若是缓存满了怎么办?LRU,LFU,FIFO
persistence strategy:若是内存满了,溢出到硬盘 -->
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap" />
</defaultCache>
xmlns:cache="http://www.springframework.org/schema/cache"
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
<!-- 配置Spring的缓存管理器 -->
<bean id="springCacheManagerSpring" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<!-- 注入ehcache的管理器 - -->
<property name="cacheManager" ref="ehCacheManager" />
</bean>
<!-- 配置缓存的注解驱动,它会自动到spring的bean中寻找缓存相关注解,并使其有效 -->
<cache:annotation-driven cache-manager="springCacheManagerSpring" />
/**
* 获取用户权限
*/
@Override
//value:缓存区域,缓存的东西往哪放
//缓存的的key的生成策略
//1.没有参数,key='0'
//2.有1个参数,那么key是对象自己,通常是对象地址
//3.有多个参数,那么key是多个对象的hash值
@Cacheable(value="SpringCache",key="#user.id")
public List<Function> findFunctionByUser(User user) {
/**
* 添加功能
*/
@Override
//清除ehcache的某区域的全部对象
@CacheEvict(value="SpringCache",allEntries=true)
public void save(Function function) {
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.0.7.Final</version>
</dependency>
<!-- 开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!-- 类缓存 -->
<!-- 指定二级缓存类 ,以及并发访问策略 -->
<class-cache usage="read-write" class="cn.aric.domain.User"/>
<!-- 集合缓存 -->
<collection-cache usage="read-write" collection="cn.aric.doain.Customer.orderSet"/>
<ehcache>
<diskStore path="f:cache" />
<defaultCache maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true" />
<cache name="hibernateCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="true" />
</ehcache>
//测试二级缓存是否配置成功
@Test
public void test(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
//获取session1
Session session1 = sessionFactory.openSession();
Transaction tx = session1.beginTransaction();
User user1 = session1.get(User.class, 10L);
System.out.println(user1.getUser_code());
tx.commit();
session1.close();
//获取session2
Session session2 = sessionFactory.openSession();
Transaction tx2 = session2.beginTransaction();
User user2 = session2.get(User.class, 10L);
System.out.println(user2.getUser_code());
tx2.commit();
session2.close();
}
<!-- 开启查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>
@Test
public void demo(){
// 查询缓存
Session s1 = factory.openSession();
s1.beginTransaction();
//1 query查询
Query q1 = s1.createQuery("from Customer");
//设置查询缓存为true
q1.setCacheable(true);
List<Customer> a1 = q1.list();
for (Customer c1 : a1) {
System.out.println(c1);
}
//2 cid =1 -- 一级缓存得到
Customer customer = (Customer) s1.get(Customer.class, 1);
System.out.println(customer);
s1.getTransaction().commit();
s1.close();
System.out.println("----------");
Session s2 = factory.openSession();
s2.beginTransaction();
//2 cid =1 -- 二级缓存得到
Customer customer2 = (Customer) s2.get(Customer.class, 1);
System.out.println(customer2);
//3 query查询
Query q2 = s2.createQuery("from Customer");
q2.setCacheable(true);
List<Customer> a2 = q2.list();
for (Customer c2 : a2) {
System.out.println(c2);
}
s2.getTransaction().commit();
s2.close();
}