/* * Copyright © 2014 YAOCHEN Corporation, All Rights Reserved */ package com.easyooo.framework.cache.impl; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.easyooo.framework.cache.CacheException; import com.easyooo.framework.cache.CacheManager; import com.easyooo.framework.cache.DataProxyException; import com.easyooo.framework.cache.Delegater; import com.easyooo.framework.cache.PropertiesMerging; /** * * 数据代理实现了持久化操作类与缓存的管理器的集成, 该类始终依赖CacheManager完成对缓存的维护, 并依赖 * <code>Delegater</code>完成数据的持久化 * * @see CacheManager * @see Delegater * * @author Killer */ public class DefaultDataProxy { Logger logger = LoggerFactory.getLogger(getClass()); private CacheManager cacheManager; /** * 为Target构造代理实例,使它具备缓存的管理 * @param cacheManager 缓存管理器 */ public DefaultDataProxy(CacheManager cacheManager) { this.cacheManager = cacheManager; } public Integer insert(final Object bean, Delegater<Integer> target) throws DataProxyException { Integer rows = target.execute(); doUpdateCallback(rows, bean, new UpdateCallback() { public void doCallback() throws CacheException { cacheManager.insert(bean); } }); return rows; } public Integer updateByPrimaryKey(final Object bean, Delegater<Integer> target) throws DataProxyException { Integer rows = target.execute(); doUpdateCallback(rows, bean, new UpdateCallback() { public void doCallback() throws CacheException { cacheManager.updateByPrimaryKey(bean); } }); return rows; } public Integer updateByPrimaryKeySelective(final Object bean, Delegater<Integer> target) throws DataProxyException { Integer rows = target.execute(); doUpdateCallback(rows, bean, new UpdateCallback() { public void doCallback() throws CacheException { cacheManager.updateByPrimaryKeySelective(bean); } }); return rows; } public Integer deleteByPrimaryKey(final Object bean, Delegater<Integer> target) throws DataProxyException { Integer rows = target.execute(); doUpdateCallback(rows, bean, new UpdateCallback() { public void doCallback() throws CacheException { cacheManager.deleteByPrimaryKey(bean); } }); return rows; } public <T> T selectByPrimaryKey(final Object bean, Delegater<T> target) throws DataProxyException { return doSelectCallback(bean, target, new SelectCallbackAdapter<T>() { @Override public T doSelectFromCache() throws CacheException { return cacheManager.selectByPrimaryKey(bean); } @Override public void doSynch(T t) throws CacheException { cacheManager.insert(t); } }); } public <T> List<T> selectByGroupKey(final Object bean, final String group, Delegater<List<T>> target) throws DataProxyException { return doSelectCallback(bean, target, new SelectCallback<List<T>>() { @Override public List<T> doSelectFromCache() throws CacheException { return cacheManager.selectByGroupKey(bean, group); } @Override public void doSynch(List<T> t) throws CacheException { cacheManager.saveSingleGroup(bean, t, group); } /** * 如果数据集合是null或者部分对象为null,则视为缓存没有命中,会自动从调用 * @see #doSynch * @param dataList * @return * @throws CacheException */ @Override public boolean hasData(List<T> dataList){ if(dataList != null){ for (T t2 : dataList) { if(t2 == null){ return false; } } return true; } return false; } }); } @SuppressWarnings("unchecked") public <T> T selectMergingByPrimaryKey(final Object bean, Delegater<T> target, final Class<T> dtoClass) throws DataProxyException { return doSelectCallback(bean, target, new SelectCallbackAdapter<T>() { @Override public T doSelectFromCache() throws CacheException { List<Map<String, Object>> values = cacheManager .selectMergingObjectByPrimaryKey(bean, dtoClass); Object dto = newMergingObject(dtoClass); PropertiesMerging pm = getMergingImplementObject(dtoClass); Object o = pm.merge(dto, values); return o != null ? (T)o : null; } @Override public void doSynch(T t) throws CacheException { // TODO Does not support } private PropertiesMerging getMergingImplementObject(Object dto){ if(dto instanceof PropertiesMerging){ return (PropertiesMerging)dto; }else{ return new OverridePropertiesMerging(); } } }); } private interface UpdateCallback{ public void doCallback()throws CacheException; } private interface SelectCallback<T>{ public T doSelectFromCache()throws CacheException; public void doSynch(T t)throws CacheException; public boolean hasData(T t); } private abstract class SelectCallbackAdapter<T> implements SelectCallback<T>{ @Override public boolean hasData(T t){ return t != null; } } private void doUpdateCallback(Integer rows, Object bean, UpdateCallback callback)throws DataProxyException{ try { if (rows == 1) { if(logger.isDebugEnabled()){ logger.debug("Cache["+ bean +"] synchronous.."); } callback.doCallback(); } } catch (CacheException e) { handleCacheException(e); } } private <T> T doSelectCallback(Object bean, Delegater<T> target,SelectCallback<T> callback)throws DataProxyException{ T t = null; try { t = callback.doSelectFromCache(); } catch (CacheException e) { handleCacheException(e); } if (!callback.hasData(t)) { if(logger.isDebugEnabled()){ logger.debug("Delegated to the database["+ bean +"]"); } t = target.execute(); if (t != null) { try { callback.doSynch(t); } catch (CacheException e) { handleCacheException(e); } } } return t; } private Object newMergingObject(Class<?> dtoClass)throws CacheException{ try { return dtoClass.newInstance(); } catch (Exception e) { throw new CacheException(e); } } private void handleCacheException(CacheException ce) throws DataProxyException { logger.error("An error occurred in the operation of the cache:", ce); } public void setCacheManager(CacheManager cacheManager) { this.cacheManager = cacheManager; } }