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

1.緩存分析

我們已經(jīng)實(shí)現(xiàn)了商品詳情頁面的展示,但是有一個(gè)問題我們要思考的是:因?yàn)椴樵兩唐吩斍榈臅r(shí)候要涉及到數(shù)據(jù)庫,如果我們網(wǎng)頁的訪問量很大的時(shí)候,查詢商品都去查數(shù)據(jù)庫的話,數(shù)據(jù)庫的壓力是很大的。為了解決這個(gè)問題的話我們要引入緩存;但是引入緩存的話又要考慮一個(gè)問題,緩存的資源也是有限的。如果我們把大量商品詳情信息都放到緩存的話,緩存的壓力也很大。我們知道商品是分熱點(diǎn)商品和冷門商品的,熱點(diǎn)訪問量很大,因此存儲(chǔ)熱門商品信息才能提高緩存的利用率。那么如何解決這個(gè)問題呢,有以下兩種方案:
1.利用redis的的訪問量統(tǒng)計(jì)功能并利用其zset數(shù)據(jù)類型進(jìn)行訪問量排序,把訪問量高的商品詳情內(nèi)容添加到緩存當(dāng)中。這種方案比較麻煩,我們不建議采用這種方式。
2.設(shè)置緩存的過期時(shí)間,用戶只要點(diǎn)擊查看商品詳情,我們一律先都存放到緩存當(dāng)中,但是我們要設(shè)置一下該條商品的緩存時(shí)間(比如半天或一天或其它),到期后該商品的緩存就會(huì)被刪除掉,如果該商品是熱門商品的話,用戶再查看詳情的時(shí)候就又會(huì)向緩存中添加該商品的緩存,如果該商品是冷門商品,過期后緩存中便沒有這款商品的緩存信息了(直到有下一位用戶查看該商品的詳情信息),這樣就可以節(jié)約緩存的空間,而且這種方式無疑是提高緩存利用率最簡(jiǎn)單的方法了。
那么我們?nèi)绾卧诰彺嬷斜4嫖覀兊男畔⒛兀?br> redis有兩種存儲(chǔ)方式,一種是哈希,一種是字符串;前者適合信息分類存儲(chǔ),但不適合設(shè)置緩存的過期時(shí)間,因?yàn)樗恢С值骄唧w到對(duì)每個(gè)Field進(jìn)行設(shè)置過期時(shí)間,這就意味著如果我們?cè)O(shè)置的key過期后,緩存的消息都會(huì)消失,這顯然是不合理的,我們想要的是針對(duì)每個(gè)商品設(shè)置過期時(shí)間,因此設(shè)置過期時(shí)間的話,hash存儲(chǔ)不合適。String存儲(chǔ)是比較適合的,那么問題又來了,String存儲(chǔ)時(shí)key是容易重復(fù)的,怎么來避免key沖突呢?我們可以通過添加前綴、后綴的方式對(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
從上面的分析我們知道我們可以通過添加緩存前綴來區(qū)分key的策略,這個(gè)key我們可以靈活一點(diǎn),還有過期時(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è)置過期時(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í)行查詢之前配置分頁條件。使用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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容