第十八篇:查詢商品詳情頁(yè)面添加緩存

1.緩存分析

我們已經(jīng)實(shí)現(xiàn)了商品詳情頁(yè)面的展示慎玖,但是有一個(gè)問(wèn)題我們要思考的是:因?yàn)椴樵兩唐吩斍榈臅r(shí)候要涉及到數(shù)據(jù)庫(kù)枣察,如果我們網(wǎng)頁(yè)的訪問(wèn)量很大的時(shí)候阳藻,查詢商品都去查數(shù)據(jù)庫(kù)的話鬼廓,數(shù)據(jù)庫(kù)的壓力是很大的肿仑。為了解決這個(gè)問(wèn)題的話我們要引入緩存;但是引入緩存的話又要考慮一個(gè)問(wèn)題碎税,緩存的資源也是有限的尤慰。如果我們把大量商品詳情信息都放到緩存的話,緩存的壓力也很大雷蹂。我們知道商品是分熱點(diǎn)商品和冷門商品的伟端,熱點(diǎn)訪問(wèn)量很大,因此存儲(chǔ)熱門商品信息才能提高緩存的利用率匪煌。那么如何解決這個(gè)問(wèn)題呢责蝠,有以下兩種方案:
1.利用redis的的訪問(wèn)量統(tǒng)計(jì)功能并利用其zset數(shù)據(jù)類型進(jìn)行訪問(wèn)量排序,把訪問(wèn)量高的商品詳情內(nèi)容添加到緩存當(dāng)中萎庭。這種方案比較麻煩霜医,我們不建議采用這種方式。
2.設(shè)置緩存的過(guò)期時(shí)間驳规,用戶只要點(diǎn)擊查看商品詳情肴敛,我們一律先都存放到緩存當(dāng)中,但是我們要設(shè)置一下該條商品的緩存時(shí)間(比如半天或一天或其它)吗购,到期后該商品的緩存就會(huì)被刪除掉医男,如果該商品是熱門商品的話,用戶再查看詳情的時(shí)候就又會(huì)向緩存中添加該商品的緩存捻勉,如果該商品是冷門商品镀梭,過(guò)期后緩存中便沒有這款商品的緩存信息了(直到有下一位用戶查看該商品的詳情信息),這樣就可以節(jié)約緩存的空間踱启,而且這種方式無(wú)疑是提高緩存利用率最簡(jiǎn)單的方法了报账。
那么我們?nèi)绾卧诰彺嬷斜4嫖覀兊男畔⒛兀?br> redis有兩種存儲(chǔ)方式撒强,一種是哈希,一種是字符串笙什;前者適合信息分類存儲(chǔ),但不適合設(shè)置緩存的過(guò)期時(shí)間胚想,因?yàn)樗恢С值骄唧w到對(duì)每個(gè)Field進(jìn)行設(shè)置過(guò)期時(shí)間琐凭,這就意味著如果我們?cè)O(shè)置的key過(guò)期后,緩存的消息都會(huì)消失浊服,這顯然是不合理的统屈,我們想要的是針對(duì)每個(gè)商品設(shè)置過(guò)期時(shí)間,因此設(shè)置過(guò)期時(shí)間的話牙躺,hash存儲(chǔ)不合適愁憔。String存儲(chǔ)是比較適合的,那么問(wèn)題又來(lái)了孽拷,String存儲(chǔ)時(shí)key是容易重復(fù)的吨掌,怎么來(lái)避免key沖突呢?我們可以通過(guò)添加前綴脓恕、后綴的方式對(duì)redis的key進(jìn)行分類膜宋,如下圖所示。既然是要存儲(chǔ)商品詳情炼幔,就在商品ID前面起個(gè)名字秋茫,就叫做ITEM_INFO(大家可以隨便起),在ID的后面添加后綴BASE(代表是基本信息)乃秀,DESC(代表是商品描述信息)
即:
ITEM_INFO:123456:BASE
ITEM_INFO:123456:DESC


image.png

如果把二維表保存到redis中:
1肛著、表名就是第一層
2、主鍵是第二層
3跺讯、字段名第三次
三層使用“:”分隔作為key枢贿,value就是字段中的內(nèi)容。

2.緩存的實(shí)現(xiàn)

我們一般把緩存加到service層中抬吟,因?yàn)镃ontroller層使用的話有一定的局限性萨咕。將緩存加到service層的話,如果是其他工程引用這個(gè)服務(wù)的話也能使用緩存的功能
下面是實(shí)現(xiàn)的步驟:
第一步:在taotao-manager-service中添加依賴



第二步:將taotao-content-service中的jedis的代碼復(fù)制一份


image.png

第三步:將配置文件復(fù)制進(jìn)去
image.png

第四步:配置resource.properties
從上面的分析我們知道我們可以通過(guò)添加緩存前綴來(lái)區(qū)分key的策略火本,這個(gè)key我們可以靈活一點(diǎn)危队,還有過(guò)期時(shí)間也是。因此我們?cè)趓esource.properties中配置
image.png

第四步:在代碼中添加緩存

package com.taotao.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taotao.common.pojo.EasyUIDataGridResult;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.mapper.TbItemDescMapper;
import com.taotao.mapper.TbItemMapper;
import com.taotao.pojo.TbItem;
import com.taotao.pojo.TbItemDesc;
import com.taotao.pojo.TbItemExample;
import com.taotao.service.ItemService;
import com.taotao.service.jedis.JedisClient;
import com.taotao.utils.IDUtils;
import com.taotao.utils.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.jms.*;
import java.util.Date;
import java.util.List;

/**
 * 商品管理
 */
@Service
public class ItemServiceImpl implements ItemService {
    @Autowired
    private TbItemMapper tbItemMapper;
    @Autowired
    private TbItemDescMapper itemDescMapper;
    @Autowired
    private JmsTemplate jmsTemplate;
    @Resource(name = "itemAddTopic")
    private Destination itemAddTopic;
    @Autowired
    private JedisClient jedisClient;
    @Value("${ITEM_INFO}")
    private String ITEM_INFO;//商品的前綴
    @Value("${ITEM_EXPIRE}")
    private Integer ITEM_EXPIRE;//商品的后綴
    @Override
    public TbItem getItemById(long itemId) {
        //查詢緩存
        try{
            String json = jedisClient.get(ITEM_INFO + ":"+ itemId + ":BASE");
            if (StringUtils.isNotBlank(json)) {
                TbItem item = JsonUtils.jsonToPojo(json,TbItem.class);
                return  item;
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
        TbItem item = tbItemMapper.selectByPrimaryKey(itemId);
        //如果在緩存中沒有就添加進(jìn)緩存
        try{
            //添加緩存
            jedisClient.set(ITEM_INFO + ":"+ itemId + ":BASE", JsonUtils.objectToJson(item));
            //設(shè)置過(guò)期時(shí)間
            jedisClient.expire(ITEM_INFO + ":"+ itemId + ":BASE",ITEM_EXPIRE);
        }catch(Exception e) {
            e.printStackTrace();
        }
        return item;
    }

    @Override
    public TbItemDesc getDescById(long itemId) {
        //查詢緩存
        try{
            String json = jedisClient.get(ITEM_INFO + ":" + itemId  + ":DESC");
            if(StringUtils.isNotBlank(json)) {
                TbItemDesc desc = JsonUtils.jsonToPojo(json,TbItemDesc.class);
                return desc;
            }
        }catch(Exception e) {

        }
        TbItemDesc desc = itemDescMapper.selectByPrimaryKey(itemId);
        //如果在緩存中沒有就添加進(jìn)緩存
        try{
            jedisClient.set(ITEM_INFO + ":" + itemId  + ":DESC",JsonUtils.objectToJson(desc));
            jedisClient.expire(ITEM_INFO + ":" + itemId  + ":DESC",ITEM_EXPIRE);
        }catch(Exception e) {
            e.printStackTrace();
        }
        return desc;
    }

    @Override
    public EasyUIDataGridResult getItemList(int page, int rows) {
        //1.在執(zhí)行查詢之前配置分頁(yè)條件钙畔。使用PageHelper的靜態(tài)方法
        PageHelper.startPage(page,rows);
        //2.執(zhí)行查詢
        TbItemExample tbItemExample = new TbItemExample();
        List<TbItem> list = tbItemMapper.selectByExample(tbItemExample);
        //3.創(chuàng)建PageInfo對(duì)象
        PageInfo<TbItem> pageInfo = new PageInfo<>(list);
        EasyUIDataGridResult result = new EasyUIDataGridResult();
        //設(shè)置數(shù)目
        result.setTotal(pageInfo.getTotal());
        //設(shè)置返回的數(shù)據(jù)
        result.setRows(list);
        return result;
    }

    @Override
    public TaotaoResult addItem(TbItem item, String desc) {
        final long id = IDUtils.genItemId();
        item.setId(id);
        item.setCreated(new Date());
        item.setUpdated(new Date());
        item.setStatus((byte) 1);
        tbItemMapper.insert(item);
        TbItemDesc itemDesc = new TbItemDesc();
        itemDesc.setItemDesc(desc);
        itemDesc.setCreated(new Date());
        itemDesc.setUpdated(new Date());
        itemDescMapper.insert(itemDesc);
        //使用ActiveMq發(fā)送消息
        jmsTemplate.send(itemAddTopic,new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                TextMessage textMessage = session.createTextMessage(id + "");
                return textMessage;
            }
        });
        return TaotaoResult.ok();
    }


    @Override
    public TbItem updateItem(long itemId) {

        return null;
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末茫陆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子擎析,更是在濱河造成了極大的恐慌簿盅,老刑警劉巖挥下,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異桨醋,居然都是意外死亡棚瘟,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門喜最,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)偎蘸,“玉大人,你說(shuō)我怎么就攤上這事瞬内∶匝” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵虫蝶,是天一觀的道長(zhǎng)章咧。 經(jīng)常有香客問(wèn)我,道長(zhǎng)能真,這世上最難降的妖魔是什么赁严? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮粉铐,結(jié)果婚禮上误澳,老公的妹妹穿的比我還像新娘。我一直安慰自己秦躯,他們只是感情好忆谓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著踱承,像睡著了一般倡缠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茎活,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天昙沦,我揣著相機(jī)與錄音,去河邊找鬼载荔。 笑死盾饮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的懒熙。 我是一名探鬼主播丘损,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼工扎!你這毒婦竟也來(lái)了徘钥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤肢娘,失蹤者是張志新(化名)和其女友劉穎呈础,沒想到半個(gè)月后舆驶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡而钞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年沙廉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片臼节。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蓝仲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出官疲,到底是詐尸還是另有隱情,我是刑警寧澤亮隙,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布途凫,位于F島的核電站,受9級(jí)特大地震影響溢吻,放射性物質(zhì)發(fā)生泄漏维费。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一促王、第九天 我趴在偏房一處隱蔽的房頂上張望犀盟。 院中可真熱鬧,春花似錦蝇狼、人聲如沸阅畴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)贱枣。三九已至,卻和暖如春颤专,著一層夾襖步出監(jiān)牢的瞬間纽哥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工栖秕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留春塌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓簇捍,卻偏偏與公主長(zhǎng)得像只壳,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子暑塑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容