您的位置:首页 > 其它

Guava Cache实现本地缓存

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

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 这篇文章讲的更详细
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: