Guava Cache实现本地缓存

我们在处理业务时,有时候会频繁地使用从数据库查出来的同一条数据,这会影响程序的效率,一般地我们希望将这条数据缓存起来。即我们希望,同一条查询语句(查询条件也是一样的),仅在第一次执行时去数据库查询,而后每次直接从缓存中调用就是了。


1 首先新建一个缓存的策略接口

/**
* 类说明:策略接口,每个策略都必须实现这个标准的策略接口
*/

public interface ILocalCache<K,V> {

	/**
	 * 根据Key获取value
	 * @param k key
	 * @return value
	 */
	V get(K k);
	
}

2 新建一个策略辅助类(封装了对Guava Cache的利用,包括cache的创建、从数据源获取数据等)

public abstract class GuavaAbstractLoadingCache<K,V> {

	private int maximumSize = 100;                 //最大缓存条数
	private int expireAfterWriteDuration = 60;      //数据存在时长 
	private TimeUnit timeUnit = TimeUnit.MINUTES;   //时间单位(分钟)    


	private LoadingCache<K, V> cache;   


	/**   
	 * 通过调用getCache().get(key)来获取数据    
	 * @return cache   
	 */    
	public LoadingCache<K, V> getCache() {    
		if(cache == null){  //使用双重校验锁保证只有一个cache实例    
			synchronized (this) {    
				if(cache == null){    
					cache = CacheBuilder.newBuilder().maximumSize(maximumSize)      //缓存数据的最大条目,也可以使用.maximumWeight(weight)代替    
							.expireAfterWrite(expireAfterWriteDuration, timeUnit)   //数据被创建多久后被移除    
//							.recordStats()                                          //启用统计   (用于缓存信息的统计 可选)
							.build(new CacheLoader<K, V>() {    
								@Override    
								public V load(K key) throws Exception {    
									return fetchData(key);    
								}    
							});    
				}    
			}    
		}    

		return cache;    
	}    

	/**   
	 * 从缓存中获取数据(第一次自动调用fetchData从外部获取数据)   
	 * @param key   
	 * @return Value   
	 * @throws ExecutionException    
	 */    
	protected V getValue(K key) throws ExecutionException {    
		V result = getCache().get(key);    
		return result;    
	}    

	/**   
	 * 根据key从数据库或其他数据源中获取一个value,并被自动保存到缓存中。   
	 * 这个方法由子类实现,以达到不同策略从不同的数据源获取缓存信息的效果
	 * @param key   
	 * @return value,连同key一起被加载到缓存中。    
	 */    
	protected abstract V fetchData(K key);    

}

3 实现一个策略 (一般地一个策略实现一个从数据源获取数据的途径)

public class CacheStrategyOne<String,Object> 
extends GuavaAbstractLoadingCache<String,Object>
implements ILocalCache<String,Object> {

	@Override
	public Object get(String k) {
		try {    
			return getValue(k);    
		} catch (Exception e) {    
			return null;    
		}  
	}

	@Override
	protected Object fetchData(String key) {
		//当缓存中没有key的缓存时,就从这个方法来获取,一般地这里会从数据源取数据,这里模拟从数据库获取数据
		
		User user = new User("1232321","zsq",22);
		System.out.println("从数据源中获取"+key);
		
		return (Object) user;
	}
}

4 新建两个测试类

public class User {
	
	public User(String id,String name,int age){
		this.id = id;
		this.name = name ;
		this.age = age;
	}
	
	private String id;
	
	private String name;
	
	private int age;
}

public class Test {

	public static void main(String[] args) {
		CacheStrategyOne one = new CacheStrategyOne();

		User user1 = (User) one.get("1");

		User user2 = (User) one.get("1");
		
		User user3 = (User) one.get("3");
	}
}


输出结果:

从数据源中获取1
从数据源中获取3


可以看到 测试类中我们调用了3次get,其中第二次没有从数据源获取数据,因为第一次获取时,已经将结果缓存了,所有第二次直接从缓存中获取

这篇文章大部分的知识点来源于 文章:http://blog.csdn.net/liuxiao723846/article/details/52330971 这篇文章讲的更详细




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值