上一篇memcached基本配置与使用http://blog.csdn.net/sup_heaven/article/details/32337711介绍了memcached的一些基本概念和一个范例。
这一篇将以介绍一个memcached在项目中的应用。假设我们有一个web应用,里面有商品信息,文章信息,评论信息,其他信息,我们希望对其做缓存,那么我们在ServiceImpl层就不在调用DAOmpl层,而是调用CacheImpl层,在CacheImpl层中判断要取出的商品信息是否已经在缓存中,如果在了,那么直接从缓存中去,如果没有这个时候还是从数据库中取,同时将它放到缓存中,以便下次使用。
第一步、新建一个常量类,用于上面的四种信息的在数组中的索引。
- publicclassMemcachedConstant{
- publicstaticfinalintMEMCACHED_GOODSDETAIL=0;
- publicstaticfinalintMEMCACHED_ARTICLEDETAIL=1;
- publicstaticfinalintMEMCACHED_COMMENTDETAIL=2;
- publicstaticfinalintMEMCACHED_OTHERDETAIL=3;
- }
第二步、由于有大量的商品信息,我们在放入缓存时必须给定一个key,那么我们最好规范的命名不同类别的key,如商品的key就是商品的前缀加上商品的编号。
- publicclassMemcachedKeyUtil{
- privatestaticfinalStringGOODS_KEY_PREFIX="goods_";
- publicstaticStringgetGoodsKey(longgoodsId){
- returnGOODS_KEY_PREFIX+goodsId;
- }
- }
第三步、我们建一个和上一篇文章中一样的工具类,用于新建pool、client,操作缓存等。这里再强调一下,一个pool关联多个server(就是会根据权重将缓存放在这些servers上),一个client会通过poolName关联具体的pool。
- publicclassMemcachedUtil{
- privateintMEMCACHED_SERVER_NUM=4;
- privateSockIOPool[]pools=newSockIOPool[MEMCACHED_SERVER_NUM];
- privateMemCachedClient[]mcs=newMemCachedClient[MEMCACHED_SERVER_NUM];
- privatefinalString[]poolNames=newString[]{"GOODSDETAIL_POOL","","",""};
- privatestaticMemcachedUtilinstance;
- privateMemcachedUtil(){
- this.init();
- }
- //单例
- publicstaticMemcachedUtilgetInstance(){
- if(MemcachedUtil.instance==null){
- synchronized(MemcachedUtil.class){
- if(MemcachedUtil.instance==null){
- MemcachedUtil.instance=newMemcachedUtil();
- }
- }
- }
- returnMemcachedUtil.instance;
- }
- publicObjectget(intindex,Stringkey){
- returnthis.mcs[index].get(key);
- }
- publicbooleanset(intindex,Stringkey,Objectvalue){
- returnthis.mcs[index].set(key,value);
- }
- publicbooleandelete(Stringkey){
- returnthis.mcs[index].delete(key);
- }
- publicMemCachedClientgetMemCachedClient(intindex){
- returnthis.mcs[index];
- }
- publicvoidinit(){
- for(inti=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]=newMemCachedClient(poolNames[i]);
- }
- }
- }
第四步、新建一个基类以供所用继承它的CacheImpl直接调用MemcachedUtil里的方法,如果不写该类那么在CacheImpl中会有很多重复的操作MemcachedUtil的代码。
- publicclassMemcachedSupport{
- publicbooleansetDetailData(Stringkey,Objectvalue){
- returnMemcachedUtil.getInstance().set(MemcachedConstant.MEMCACHED_DETAIL,key,value);
- }
- publicObjectgetDetailData(Stringkey){
- returnMemcachedUtil.getInstance().get(MemcachedConstant.MEMCACHED_DETAIL,key);
- }
- publicbooleandeleteDetailData(Stringkey){
- returnMemcachedUtil.getInstance().delete(MemcachedConstant.MEMCACHED_DETAIL);
- }
- }
第五步、新建一个GoodsCacheImpl,该类的作用就是一开始所说的,娶不到缓存,就调用DAO查询并放入缓存,如果缓存中有就直接从缓存中拿。
- publicclassGoodsCacheImplextendsMemcachedSupport{
- @Resource(name="goodsDaoImpl")
- privateGoodsDaogoodsDao;
- publicGoodsselectGoodsById(longgoodsId){
- Goodsgoods=null;
- StringgoodsKey=MemcachedKeyUtil.getGoodsKey(goodsId);
- goods=(Goods)getDetailData(goodsKey);
- if(goods==null){
- goods=goodsDao.selectGoodsById(goodsId,false);
- if(goods!=null){
- setDetailData(goodsKey,goods);
- }
- }
- returngoods;
- }
- }
这样就在你的应用中使用了memcached,不过上面的只是部分代码,跑不起来的哦。