hibernate二级缓存(三) 自定义实现一个简单的hibernate二级缓存
前面我们已经提及过hibernate内部为二级缓存的扩展做了很多的实现。我们只需要实现RegionFactoryTemplate和DomainDataStorageAccess即可自已实现hibernate缓存。在DomainDataStorageAccess实现中可以将缓存放置到redis或者memcache,来实现分布式的二级缓存。下面用hashmap实现了一个简单的二级缓存。
1. 实现RegionFactoryTemplate
RegionFactoryTemplate模版类为实现RegionFactory简化了很多操作。通常需要实现以下几个方法
//创建查询结果缓存,该缓存用于hibernate的查询缓存
StorageAccess createQueryResultsRegionStorageAccess(String regionName, SessionFactoryImplementor sessionFactory);
//创建时间戳缓存
StorageAccess createTimestampsRegionStorageAccess(String regionName, SessionFactoryImplementor sessionFactory);
//创建实体缓存
DomainDataStorageAccess createDomainDataStorageAccess(DomainDataRegionConfig regionConfig, DomainDataRegionBuildingContext buildingContext);
//简单的理解为初始化之前需要做的一些准备工作
void prepareForUse(SessionFactoryOptions settings, Map configValues);
//释放缓存
void releaseFromUse() ;
从RegionFactoryTemplate的实现不难看出实际上是通过StorageAccess 来管理缓存的。简化了之前讲过的DomainDataRegion,EntityDataAccess等实现细节。
实现类如下:
public class MyRegionFactoryImpl extends RegionFactoryTemplate {
private static final long serialVersionUID = -401479360060731148L;
//缓存管理器
private volatile CacheManager cacheManager;
@Override
protected StorageAccess createQueryResultsRegionStorageAccess(String regionName, SessionFactoryImplementor sessionFactory) {
return new MyDomainDataStorageAccess(getOrCreateCache(regionName));
}
private Cache getOrCreateCache(String regionName) {
Cache cache = cacheManager.getCache(regionName);
if (cache == null) {
return createCache(regionName);
}
return cache;
}
private Cache createCache(String regionName) {
cacheManager.addCache(regionName);
return cacheManager.getCache(regionName);
}
@Override
protected StorageAccess createTimestampsRegionStorageAccess(String regionName, SessionFactoryImplementor sessionFactory) {
return new MyDomainDataStorageAccess(getOrCreateCache(regionName));
}
/**
* 该方法必须覆盖RegionFactoryTemplate的方法,RegionFactoryTemplate默认实现是抛出异常
*
* @param regionConfig
* @param buildingContext
* @return
*/
@Override
protected DomainDataStorageAccess createDomainDataStorageAccess(DomainDataRegionConfig regionConfig, DomainDataRegionBuildingContext buildingContext) {
return new MyDomainDataStorageAccess(getOrCreateCache(regionConfig.getRegionName()));
}
@Override
protected void prepareForUse(SessionFactoryOptions settings, Map configValues) {
this.cacheManager = new CacheManager();
//一个打印缓存内容的线程,用于观察缓存里面的内容
/*Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(cacheManager);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();*/
}
@Override
protected void releaseFromUse() {
cacheManager = null;
}
}
通过MyDomainDataStorageAccess内部包含一个cache对象,CacheManager来创建和管理cache对象。
2. 实现DomainDataStorageAccess
DomainDataStorageAccess内部通过Cache类来真正的访问缓存,这样不同的cache类就能访问不同的缓存。将缓存的访问和缓存的具体实现分离。
DomainDataStorageAccess的实现代码如下:
public class MyDomainDataStorageAccess implements DomainDataStorageAccess {
private Cache cache;
public MyDomainDataStorageAccess(Cache cache) {
this.cache = cache;
}
@Override
public Object getFromCache(Object key, SharedSessionContractImplementor session) {
return cache.get(key);
}
@Override
public void putIntoCache(Object key, Object value, SharedSessionContractImplementor session) {
cache.put(key, value);
}