天天看點

redis存儲list集合_Redis實戰(3)-資料結構List實戰一之商品資訊的有序存儲摘要内容

摘要

電商平台的管理後端一般有兩大角色的使用者可以使用,一個是系統管理者,一個是平台的賣家/商家,對于商家而言,管理自個兒的商品是日常工作中再為普通不過的事情了,本文我們将以"有序存儲并展示電商平台中商家上傳的各式各樣的商品清單",這裡的關鍵詞是"有序存儲與展示",我們将借助緩存中間件Redis的資料結構~清單List進行實戰實作!

内容

對于Redis的資料結構~清單List,在實際的項目開發實戰中,也算是其中一種比較常見、應用也比較廣泛的資料結構吧!

其底層資料存儲結構跟JavaSE集合體系的List有極其相似之處,即資料在底層是有序、排好順序的,在将清單的資料擷取出來的時候,會發現其中的資料确實是已經排好順序的了,給大家繪制了一個簡單的List的存儲和擷取流程圖,如下所示:

redis存儲list集合_Redis實戰(3)-資料結構List實戰一之商品資訊的有序存儲摘要内容

從該圖中,可以看出,當我們往Redis的清單List中添加資料時,具有"先進先出"的特性,即所謂的"FIFO"(有點隊列Queue的特性!),而且資料是緊湊、一個挨着一個存儲的!

即當我們在往緩存Redis的清單List添加資料時,可以采用"LPush 即從左邊的方向添加"的方式往緩存Redis的List中添加,然後再采用"LPop 即從左邊的方向彈出資料"或者"RPop 即從右邊的方向彈出資料"的方式擷取這一有序存儲的清單資料!

知道了清單List的資料存儲和讀取流程,其實我們也就幾乎知曉了在實際的項目實戰開發中的代碼實作了。

下面我們以"電商平台~商家添加/下架商品時如何将其商品清單有序存儲至緩存Redis的List中,每次擷取商家目前的商品清單時可以直接從緩存中讀取,減少每個商家在每次登陸之後都需要走資料庫DB頻繁查詢 所帶來的壓力!"

(1)首先,當然是需要來個"産品資訊表"啦,其完整的DDL(即資料定義語言)如下所示:

CREATE TABLE `product` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `name` varchar(255) CHARACTER SET utf8mb4 NOT NULL COMMENT '商品名稱',  `user_id` int(11) NOT NULL COMMENT '所屬商戶id',  `scan_total` int(255) DEFAULT NULL COMMENT '浏覽量',  `is_active` tinyint(255) DEFAULT '1' COMMENT '是否有效',  PRIMARY KEY (`id`),  KEY `indx_scan_total` (`scan_total`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商戶商品表';           

(2)然後,當然是需要開發一個Controller啦,在該Controller中我們需要開設兩個請求方法,一個是給商戶使用的"添加商品"(進DB,并塞入Redis),另外一個是擷取目前商戶已添加的"商品清單",其完整的源代碼如下所示:

/** * 清單List實戰-商戶商品清單存儲 * @Author:debug (SteadyJack) * @Link: weixin-> debug0868 qq-> 1948831260 * @Date: 2019/10/30 20:58 **/@[email protected]("list")public class ListController extends AbstractController{    @Autowired    private ListService listService;    //添加    @RequestMapping(value = "put",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)    public BaseResponse put(@RequestBody Product product,BindingResult result){        BaseResponse response=new BaseResponse(StatusCode.Success);        try {            log.info("--商戶商品資訊:{}",product);            response.setData(listService.addProduct(product));        }catch (Exception e){            log.error("--List實戰-商戶商品-添加-發生異常:",e.fillInStackTrace());            response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());        }        return response;    }    //擷取清單詳情    @RequestMapping(value = "get",method = RequestMethod.GET)    public BaseResponse get(@RequestParam("userId") final Integer userId){        BaseResponse response=new BaseResponse(StatusCode.Success);        try {            response.setData(listService.getHistoryProducts(userId));        }catch (Exception e){            log.error("--List實戰-商戶商品-擷取清單-發生異常:",e.fillInStackTrace());            response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());        }        return response;    }}           

(3)緊接着,我們需要開發Controller對應的Service,其職責當然是用來處理真正的業務邏輯,"添加商品"時,它負責将該商品資訊添加進DB資料庫,并添加進緩存Redis中;"擷取商品"時,自然而然是從緩存Redis擷取出List清單資料,其完整的源代碼如下所示:

/** * 清單List服務 * @Author:debug (SteadyJack) * @Link: weixin-> debug0868 qq-> 1948831260 * @Date: 2019/10/30 9:48 **/@Servicepublic class ListService {    public static final Logger log= LoggerFactory.getLogger(ListService.class);    @Autowired    private ProductMapper productMapper;    @Autowired    private RedisTemplate redisTemplate;    //添加商品    @Transactional(rollbackFor = Exception.class)    public Integer addProduct(Product product) throws Exception{        if (product!=null){            product.setId(null);   //将該商品塞入資料庫DB中            productMapper.insertSelective(product);            Integer id=product.getId();            if (id>0){  //将該商品塞入緩存Redis中                this.pushRedisService(product);            }            return id;        }        return -1;    }    //TODO:往緩存中塞資訊-可以抽取到ListRedisService    private void pushRedisService(final Product product) throws Exception{        ListOperations listOperations=redisTemplate.opsForList();        listOperations.leftPush(Constant.RedisListPrefix+product.getUserId(),product);    }    //擷取曆史釋出的商品清單    public List getHistoryProducts(final Integer userId) throws Exception{        List list= Lists.newLinkedList();        ListOperations listOperations=redisTemplate.opsForList();        final String key=Constant.RedisListPrefix+userId;        //TODO:倒序->userID=10010 ->Rabbitmq入門與實戰,Redis入門與實戰,SpringBoot項目實戰        list=listOperations.range(key,0,listOperations.size(key));        log.info("--倒序:{}",list);        //TODO:順序->userID=10010 ->SpringBoot項目實戰,Redis入門與實戰,Rabbitmq入門與實戰        //Collections.reverse(list);        //log.info("--順序:{}",list);        //TODO:彈出來移除的方式        //Product entity=listOperations.rightPop(key);        //while (entity!=null){            //list.add(entity);            //entity=listOperations.rightPop(key);        //}        return list;    }}           

(4)至此,我們的代碼實戰就完畢了,最後我們就基于Postman進入測試環節吧,我們給商戶10010添加兩個商品吧,如下所示:

redis存儲list集合_Redis實戰(3)-資料結構List實戰一之商品資訊的有序存儲摘要内容
redis存儲list集合_Redis實戰(3)-資料結構List實戰一之商品資訊的有序存儲摘要内容

完成之後還可以前往資料庫Mysql中檢視剛剛已經添加完成的商品清單,如下圖所示:

redis存儲list集合_Redis實戰(3)-資料結構List實戰一之商品資訊的有序存儲摘要内容

最後,我們再在Postman發起"擷取目前商戶已經添加完成的商品清單-有序展示"(可以通過修改代碼的方式,實作"順序"、"倒序"等功效),如下所示:

redis存儲list集合_Redis實戰(3)-資料結構List實戰一之商品資訊的有序存儲摘要内容

好了,本篇文章我們就介紹到這裡了,建議各位小夥伴一定要照着文章提供的樣例代碼撸一撸,隻有撸過才能知道這玩意是咋用的,否則就成了"空談者"!

對Redis相關技術棧以及實際應用場景實戰感興趣的小夥伴可以前往Debug搭建的技術社群的課程中心進行學習觀看: !

其他相關的技術,感興趣的小夥伴可以關注底部Debug的技術公衆号,或者加Debug的微信,拉你進"微信版"的真正技術交流群!一起學習、共同成長!

繼續閱讀