欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Guava Cache实现本地缓存

程序员文章站 2022-06-19 11:33:03
...

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


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 这篇文章讲的更详细




上一篇: Spring Security

下一篇: 连接数据库