这一篇将以介绍一个memcached在项目中的应用。假设我们有一个web应用,里面有商品信息,文章信息,评论信息,其他信息,我们希望对其做缓存,那么我们在ServiceImpl层就不在调用DAOmpl层,而是调用CacheImpl层,在CacheImpl层中判断要取出的商品信息是否已经在缓存中,如果在了,那么直接从缓存中去,如果没有这个时候还是从数据库中取,同时将它放到缓存中,以便下次使用。
第一步、新建一个常量类,用于上面的四种信息的在数组中的索引。
public class MemcachedConstant { public static final int MEMCACHED_GOODSDETAIL = 0; public static final int MEMCACHED_ARTICLEDETAIL = 1; public static final int MEMCACHED_COMMENTDETAIL = 2; public static final int MEMCACHED_OTHERDETAIL = 3; }
public class MemcachedKeyUtil { private static final String GOODS_KEY_PREFIX = "goods_"; public static String getGoodsKey(long goodsId) { return GOODS_KEY_PREFIX + goodsId; } }
第三步、我们建一个和上一篇文章中一样的工具类,用于新建pool、client,操作缓存等。这里再强调一下,一个pool关联多个server(就是会根据权重将缓存放在这些servers上),一个client会通过poolName关联具体的pool。
public class MemcachedUtil { private int MEMCACHED_SERVER_NUM = 4; private SockIOPool[] pools = new SockIOPool[MEMCACHED_SERVER_NUM]; private MemCachedClient[] mcs = new MemCachedClient[MEMCACHED_SERVER_NUM]; private final String[] poolNames = new String[] { "GOODSDETAIL_POOL", "", "", "" }; private static MemcachedUtil instance; private MemcachedUtil() { this.init(); } // 单例 public static MemcachedUtil getInstance() { if (MemcachedUtil.instance == null) { synchronized (MemcachedUtil.class) { if (MemcachedUtil.instance == null) { MemcachedUtil.instance = new MemcachedUtil(); } } } return MemcachedUtil.instance; } public Object get(int index, String key) { return this.mcs[index].get(key); } public boolean set(int index, String key, Object value) { return this.mcs[index].set(key, value); } public boolean delete(String key) { return this.mcs[index].delete(key); } public MemCachedClient getMemCachedClient(int index) { return this.mcs[index]; } public void init() { for (int i = 0; i < MEMCACHED_SERVER_NUM; ++i) { this.pools[i] = SockIOPool.getInstance(poolNames[i]); this.pools[i].setServers(servers); this.pools[i].setWeights(weights); this.pools[i].setInitConn(initConn); this.pools[i].setMinConn(minConn); this.pools[i].setMaxConn(maxConn); this.pools[i].setMaxIdle(maxIdle); this.pools[i].setMaxBusyTime(maxBusyTime); this.pools[i].setMaintSleep(maintSleep); this.pools[i].setNagle(ifNagle); this.pools[i].setSocketTO(socketTO); this.pools[i].setSocketConnectTO(socketConnectTO); this.pools[i].setFailover(ifFailOver); this.pools[i].setFailback(ifFailback); this.pools[i].setAliveCheck(ifAliveCheck); this.pools[i].initialize(); this.mcs[i] = new MemCachedClient(poolNames[i]); } } }
第四步、新建一个基类以供所用继承它的CacheImpl直接调用MemcachedUtil里的方法,如果不写该类那么在CacheImpl中会有很多重复的操作MemcachedUtil的代码。
public class MemcachedSupport { public boolean setDetailData(String key, Object value) { return MemcachedUtil.getInstance().set(MemcachedConstant.MEMCACHED_DETAIL, key, value); } public Object getDetailData(String key) { return MemcachedUtil.getInstance().get(MemcachedConstant.MEMCACHED_DETAIL, key); } public boolean deleteDetailData(String key) { return MemcachedUtil.getInstance().delete(MemcachedConstant.MEMCACHED_DETAIL); } }
第五步、新建一个GoodsCacheImpl,该类的作用就是一开始所说的,娶不到缓存,就调用DAO查询并放入缓存,如果缓存中有就直接从缓存中拿。
public class GoodsCacheImpl extends MemcachedSupport{ @Resource(name = "goodsDaoImpl") private GoodsDao goodsDao; public Goods selectGoodsById(long goodsId) { Goods goods = null; String goodsKey = MemcachedKeyUtil.getGoodsKey(goodsId); goods = (Goods) getDetailData(goodsKey); if (goods == null) { goods = goodsDao.selectGoodsById(goodsId, false); if (goods != null) { setDetailData(goodsKey, goods); } } return goods; } }
原文链接 :