简单从这几个方面描述一下如何使用Cache,对Cache的各种原理介绍此处不涉及.
1.使用场景
2.如何使用Cache
3.创建方式
4. 如何和Spring搭配使用
+------------------------------------------------------分割心吖-------------------------------------------------------+
1. Cache的使用场景
一般而言,对于那些频繁需要查询比对的热点数据,我们采用使用缓存,对于数据量较小的,几条,几十条数据,而且需要加缓存的接口较少,这时候我们会采用Cache,建议使用Google提供的guava Cache,它简单易用的同时,性能也好. 而且线程安全(原因看源码) .对于那些较大数据量的,或者需要加缓存的接口较多的项目,可以去考虑Redis,memcached等等
2. 如何使用Cache
和Map的使用方式差不多,也可以和Spring结合,使用@Cacheable注解使用.
3. 创建方式
1. Cache Callable
2. LoadingCache
方式一:
1 package info.sanaulla.cache; 2 3 import com.google.common.cache.Cache; 4 import com.google.common.cache.CacheBuilder; 5 import org.junit.Test; 6 7 import java.util.concurrent.Callable; 8 import java.util.concurrent.ExecutionException; 9 import java.util.concurrent.TimeUnit; 10 11 /** 12 * ********************************************************* 13 * <p/> 14 * Author: XiJun.Gong 15 * Date: 2016-08-17 16:59 16 * Version: default 1.0.0 17 * Class description: 18 * <p/> 19 * ********************************************************* 20 */ 21 public class CacheDemo { 22 private static Cache<Object, Object> cache = CacheBuilder.newBuilder() 23 .maximumSize(100).expireAfterWrite(24, TimeUnit.HOURS) 24 .recordStats() 25 .build(); 26 27 public static Object get(Object key) throws ExecutionException { 28 29 Object var = cache.get(key, new Callable<Object>() { 30 @Override 31 public Object call() throws Exception { 32 System.out.println("如果没有值,就执行其他方式去获取值"); 33 String var = "Google.com.sg"; 34 return var; 35 } 36 }); 37 return var; 38 } 39 40 public static void put(Object key, Object value) { 41 cache.put(key, value); 42 } 43 44 class Person { 45 private String name; 46 private Integer age; 47 48 public Person() { 49 } 50 51 public Person(String name, Integer age) { 52 this.name = name; 53 this.age = age; 54 } 55 56 public String getName() { 57 return name; 58 } 59 60 public void setName(String name) { 61 this.name = name; 62 } 63 64 public Integer getAge() { 65 return age; 66 } 67 68 public void setAge(Integer age) { 69 this.age = age; 70 } 71 72 @Override 73 public String toString() { 74 return "Person{" + 75 "名字=‘" + name + ‘\‘‘ + 76 ", 年纪=" + age + 77 ‘}‘; 78 } 79 } 80 81 @Test 82 public void CacheTest() throws ExecutionException { 83 84 Person person = new Person(); 85 person.setAge(11); 86 person.setName("tSun"); 87 System.out.println(CacheDemo.get("man")); 88 CacheDemo.put("man", new Person("hopg", 123)); 89 System.out.println(CacheDemo.get("man")); 90 System.out.println(CacheDemo.get("man")); 91 92 System.out.println(CacheDemo.get("person").toString()); 93 CacheDemo.put("person", person); 94 System.out.println(CacheDemo.get("person").toString()); 95 System.out.println(CacheDemo.get("person").toString()); 96 97 System.out.println(CacheDemo.get("woman")); 98 CacheDemo.put("women", new Person("google", 666)); 99 System.out.println(CacheDemo.get("woman")); 100 System.out.println(CacheDemo.get("woman")); 101 System.out.println(CacheDemo.get("man")); 102 } 103 }
结果:
1 如果没有值,就执行其他方式去获取值 2 Google.com.sg 3 Person{名字=‘hopg‘, 年纪=123} 4 Person{名字=‘hopg‘, 年纪=123} 5 如果没有值,就执行其他方式去获取值 6 Google.com.sg 7 Person{名字=‘tSun‘, 年纪=11} 8 Person{名字=‘tSun‘, 年纪=11} 9 如果没有值,就执行其他方式去获取值 10 Google.com.sg 11 Google.com.sg 12 Google.com.sg 13 Person{名字=‘hopg‘, 年纪=123}
方式二:
1 package info.sanaulla.cache; 2 3 import com.google.common.cache.CacheBuilder; 4 import com.google.common.cache.CacheLoader; 5 import com.google.common.cache.LoadingCache; 6 import org.junit.Test; 7 8 import java.util.concurrent.ExecutionException; 9 import java.util.concurrent.TimeUnit; 10 11 /** 12 * ********************************************************* 13 * <p/> 14 * Author: XiJun.Gong 15 * Date: 2016-08-17 15:00 16 * Version: default 1.0.0 17 * Class description: 18 * <p>Cache Demo</p> 19 * <p/> 20 * ********************************************************* 21 */ 22 public class CacheUtil { 23 24 25 private static LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() 26 .maximumSize(2) 27 .expireAfterAccess(24, TimeUnit.HOURS) 28 .recordStats() 29 .build(new CacheLoader<Object, Object>() { 30 31 @Override 32 public Object load(Object key) throws Exception { 33 return key; 34 } 35 }); 36 37 public static Object get(Object key) throws ExecutionException { 38 Object var = cache.get(key); 39 40 if (var.equals(key)) { 41 42 System.out.println("执行其他操作,查询该值"); 43 /**执行其他操作,获取值**/ 44 Object object = "Google.com.hk"; 45 put(key, object); 46 } else { 47 System.out.println("从Cache中取值...."); 48 } 49 return cache.get(key); 50 } 51 52 public static void put(Object key, Object value) { 53 cache.put(key, value); 54 } 55 56 class Person { 57 private String name; 58 private Integer age; 59 60 public Person() { 61 } 62 63 public Person(String name, Integer age) { 64 this.name = name; 65 this.age = age; 66 } 67 68 public String getName() { 69 return name; 70 } 71 72 public void setName(String name) { 73 this.name = name; 74 } 75 76 public Integer getAge() { 77 return age; 78 } 79 80 public void setAge(Integer age) { 81 this.age = age; 82 } 83 84 @Override 85 public String toString() { 86 return "Person{" + 87 "名字=‘" + name + ‘\‘‘ + 88 ", 年纪=" + age + 89 ‘}‘; 90 } 91 } 92 93 @Test 94 public void TestCache() throws ExecutionException { 95 96 Person person = new Person(); 97 person.setAge(11); 98 person.setName("tSun"); 99 System.out.println(CacheUtil.get("man")); 100 CacheUtil.put("man", new Person("hopg", 123)); 101 System.out.println(CacheUtil.get("man")); 102 System.out.println(CacheUtil.get("man")); 103 104 System.out.println(CacheUtil.get("person").toString()); 105 CacheUtil.put("person", person); 106 System.out.println(CacheUtil.get("person").toString()); 107 System.out.println(CacheUtil.get("person").toString()); 108 109 System.out.println(CacheUtil.get("woman")); 110 CacheUtil.put("women", new Person("google", 666)); 111 System.out.println(CacheUtil.get("woman")); 112 System.out.println(CacheUtil.get("woman")); 113 System.out.println(CacheUtil.get("man")); 114 } 115 }
结果:
1 执行其他操作,查询该值 2 Google.com.hk 3 从Cache中取值.... 4 Person{名字=‘hopg‘, 年纪=123} 5 从Cache中取值.... 6 Person{名字=‘hopg‘, 年纪=123} 7 执行其他操作,查询该值 8 Google.com.hk 9 从Cache中取值.... 10 Person{名字=‘tSun‘, 年纪=11} 11 从Cache中取值.... 12 Person{名字=‘tSun‘, 年纪=11} 13 执行其他操作,查询该值 14 Google.com.hk 15 从Cache中取值.... 16 Google.com.hk 17 从Cache中取值.... 18 Google.com.hk 19 执行其他操作,查询该值 20 Google.com.hk
4. 如何和Spring结合使用
4.1 首先简单了解一下@Cacheable,@CachePut,@CacheEvit
对于cache和数据操作进行一个功能对应,如下图.
cache sql
Cacheable --save/insert
CachePut --update/Insert
CacheEvit --remove/delete
4.2 配置spring配置文件applicationContext.xml
1 <!-- cache --> 2 <bean id="cacheManager" class="com.data.cache.guava.GuavaCacheManager" 3 p:transactionAware="true"> 4 <property name="caches"> 5 <list> 6 <bean class="com.data.cache.guava.GuavaCacheFactoryBean" name="Person-cache"/> 7 <bean class="com.data.cache.guava.GuavaCacheFactoryBean" name="Modules-cache"/> 8 </list> 9 </property> 10 </bean>
部分代码:
1 @Override 2 @Cacheable(value = "Modules-cache") 3 public Collection<Module> getModule(String name) { 4 return module.get(checkNotNull(name)); 5 } 6 7 @Override 8 @Transactional(readOnly = false) 9 @CacheEvict(value = "Modules-cache", key = "#modules.name") 10 public void createModule(Modules post) { 11 ModuleDao.create(checkNotNull(module)); 12 }
5. 扩展
在github上看到一篇关于,对于overflow时候,将数据写入到文件系统的例子,还不错,如果有这方面的需求可以看看.
地址:https://github.com/raphw/guava-cache-overflow-extension