最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

利用Redis實(shí)現(xiàn)點(diǎn)贊功能的示例代碼

 更新時(shí)間:2022年06月28日 15:25:30   作者:阿Q說(shuō)代碼  
點(diǎn)贊對(duì)我們來(lái)說(shuō)并不陌生,我們經(jīng)常會(huì)在手機(jī)軟件或者網(wǎng)頁(yè)中看到它。今天就讓我們來(lái)了解一下如何用Redis實(shí)現(xiàn)這一功能吧,感興趣的可以嘗試一下

提到點(diǎn)贊,大家一想到的是不是就是朋友圈的點(diǎn)贊呀?其實(shí)點(diǎn)贊對(duì)我們來(lái)說(shuō)并不陌生,我們經(jīng)常會(huì)在手機(jī)軟件或者網(wǎng)頁(yè)中看到它,今天就讓我們來(lái)了解一下它的實(shí)現(xiàn)吧。我們常見(jiàn)的設(shè)計(jì)思路大概分為兩種:一種自然是用 MySQL 等數(shù)據(jù)庫(kù)直接落地存儲(chǔ), 另外一種就是將點(diǎn)贊的數(shù)據(jù)保存到 Redis 等緩存里,在一定時(shí)間后刷回 MySQL 等數(shù)據(jù)庫(kù)。

MySQL 和 Redis優(yōu)缺點(diǎn)

首先我們來(lái)說(shuō)一下兩種方法各自的優(yōu)缺點(diǎn):我們以 MySQL 和 Redis 為例。

1、直接寫入數(shù)據(jù)庫(kù):

優(yōu)點(diǎn):這種方法實(shí)現(xiàn)簡(jiǎn)單,只需完成數(shù)據(jù)庫(kù)的增刪改查就行;

缺點(diǎn):數(shù)據(jù)庫(kù)讀寫壓力大,如果遇到熱門文章在短時(shí)間內(nèi)被大量點(diǎn)贊的情況,直接操作數(shù)據(jù)庫(kù)會(huì)給數(shù)據(jù)庫(kù)帶來(lái)巨大壓力,影響效率。

2、使用 Redis 緩存:

優(yōu)點(diǎn):性能高,讀寫速度快,緩解數(shù)據(jù)庫(kù)讀寫的壓力;

缺點(diǎn):開發(fā)復(fù)雜,不能保證數(shù)據(jù)安全性即 redis 掛掉的時(shí)候會(huì)丟失數(shù)據(jù), 同時(shí)不及時(shí)同步 redis 中的數(shù)據(jù), 可能會(huì)在 redis 內(nèi)存置換的時(shí)候被淘汰掉。不過(guò)對(duì)于點(diǎn)贊數(shù)據(jù)我們不需要那么精確,丟失一點(diǎn)數(shù)據(jù)問(wèn)題不大。

接下來(lái)就從以下三個(gè)方面對(duì)點(diǎn)贊功能做詳細(xì)的介紹

•Redis 緩存設(shè)計(jì)

•數(shù)據(jù)庫(kù)設(shè)計(jì)

•開啟定時(shí)任務(wù)持久化存儲(chǔ)到數(shù)據(jù)庫(kù)

1、Redis 緩存設(shè)計(jì)及實(shí)現(xiàn)

Redis 的整合我們?cè)谏弦黄恼轮幸呀?jīng)介紹過(guò)了,此處就不再贅述了。我們了解到,我們?cè)谧鳇c(diǎn)贊的時(shí)候需要記錄以下幾類數(shù)據(jù):一類是某用戶被其他用戶點(diǎn)贊的詳細(xì)記錄,一類是。考慮到查詢與存取方便快捷,我這邊采用 Hash 結(jié)構(gòu)進(jìn)行存儲(chǔ),存儲(chǔ)結(jié)構(gòu)如下:

(1)某用戶被其他用戶點(diǎn)贊的詳細(xì)記錄: MAP_USER_LIKED 為鍵值, 被點(diǎn)贊用戶id::點(diǎn)贊用戶id 為 filed, 1或者0 為 value

(2)某用戶被點(diǎn)贊的數(shù)量統(tǒng)計(jì): MAP_USER_LIKED_COUNT 為鍵值, 被點(diǎn)贊用戶id 為 filed, count 為 value

部分代碼如下

/**
* 將用戶被其他用戶點(diǎn)贊的數(shù)據(jù)存到redis
*/
@Override
public void saveLiked2Redis(String likedUserId, String likedPostId) {
    String key = RedisKeyUtils.getLikedKey(likedUserId, likedPostId);
    redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED,key, LikedStatusEnum.LIKE.getCode());
}

//取消點(diǎn)贊
@Override
public void unlikeFromRedis(String likedUserId, String likedPostId) {
    String key = RedisKeyUtils.getLikedKey(likedUserId, likedPostId);
    redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED,key,LikedStatusEnum.UNLIKE.getCode());
}

/**
* 將被點(diǎn)贊用戶的數(shù)量+1
*/
@Override
public void incrementLikedCount(String likedUserId) {
    redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT,likedUserId,1);
}

//-1
@Override
public void decrementLikedCount(String likedUserId) {
    redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, likedUserId, -1);
}

/**
* 獲取Redis中的用戶點(diǎn)贊詳情記錄
*/
@Override
public List<UserLikeDetail> getLikedDataFromRedis() {
    Cursor<Map.Entry<Object,Object>> scan = redisTemplate.opsForHash().scan(RedisKeyUtils.MAP_KEY_USER_LIKED, ScanOptions.NONE);
    List<UserLikeDetail> list = new ArrayList<>();
    while (scan.hasNext()){
        Map.Entry<Object, Object> entry = scan.next();
        String key = (String) entry.getKey();
        String[] split = key.split("::");
        String likedUserId = split[0];
        String likedPostId = split[1];
        Integer value = (Integer) entry.getValue();
        //組裝成 UserLike 對(duì)象
        UserLikeDetail userLikeDetail = new UserLikeDetail(likedUserId, likedPostId, value);
        list.add(userLikeDetail);
        //存到 list 后從 Redis 中刪除
        redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED, key);
    }
    return list;
}

/**
* 獲取Redis中的用戶被點(diǎn)贊數(shù)量
*/
@Override
public List<UserLikCountDTO> getLikedCountFromRedis() {
    Cursor<Map.Entry<Object,Object>> cursor = redisTemplate.opsForHash().scan(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, ScanOptions.NONE);
    List<UserLikCountDTO> list = new ArrayList<>();
    while(cursor.hasNext()){
        Map.Entry<Object, Object> map = cursor.next();
        String key = (String) map.getKey();
        Integer value = (Integer) map.getValue();
        UserLikCountDTO userLikCountDTO = new UserLikCountDTO(key,value);
        list.add(userLikCountDTO);
        //存到 list 后從 Redis 中刪除
        redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT,key);
    }
    return list;
}

Redis 存儲(chǔ)結(jié)構(gòu)如圖

2、數(shù)據(jù)庫(kù)設(shè)計(jì)

這里我們可以和直接將點(diǎn)贊數(shù)據(jù)存到數(shù)據(jù)庫(kù)一樣,設(shè)計(jì)兩張表:

(1)用戶被其他用戶點(diǎn)贊的詳細(xì)記錄:user_like_detail

DROP TABLE IF EXISTS `user_like_detail`;
CREATE TABLE `user_like_detail`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `liked_user_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '被點(diǎn)贊的用戶id',
  `liked_post_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '點(diǎn)贊的用戶id',
  `status` tinyint(1) NULL DEFAULT 1 COMMENT '點(diǎn)贊狀態(tài),0取消,1點(diǎn)贊',
  `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '創(chuàng)建時(shí)間',
  `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改時(shí)間',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `liked_user_id`(`liked_user_id`) USING BTREE,
  INDEX `liked_post_id`(`liked_post_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用戶點(diǎn)贊表' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

(2)用戶被點(diǎn)贊的數(shù)量統(tǒng)計(jì):user_like_count

DROP TABLE IF EXISTS `user_like_count`;
CREATE TABLE `user_like_count`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `like_num` int(11) NULL DEFAULT 0,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

3、開啟定時(shí)任務(wù)持久化存儲(chǔ)到數(shù)據(jù)庫(kù)

我們使用 Quartz 來(lái)實(shí)現(xiàn)定時(shí)任務(wù),將 Redis 中的數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)中,為了演示效果,我們可以設(shè)置一分鐘或者兩分鐘存儲(chǔ)一遍數(shù)據(jù),這個(gè)視具體業(yè)務(wù)而定。在同步數(shù)據(jù)的過(guò)程中,我們首先要將 Redis 中的數(shù)據(jù)在數(shù)據(jù)庫(kù)中進(jìn)行查重,舍棄重復(fù)數(shù)據(jù),這樣我們的數(shù)據(jù)才會(huì)更加準(zhǔn)確。

部分代碼如下

//同步redis的用戶點(diǎn)贊數(shù)據(jù)到數(shù)據(jù)庫(kù)
@Override
@Transactional
public void transLikedFromRedis2DB() {
    List<UserLikeDetail> list = redisService.getLikedDataFromRedis();
    list.stream().forEach(item->{
        //查重
        UserLikeDetail userLikeDetail = userLikeDetailMapper.selectOne(new LambdaQueryWrapper<UserLikeDetail>()
           .eq(UserLikeDetail::getLikedUserId, item.getLikedUserId())
           .eq(UserLikeDetail::getLikedPostId, item.getLikedPostId()));
        if (userLikeDetail == null){
            userLikeDetail = new UserLikeDetail();
            BeanUtils.copyProperties(item, userLikeDetail);
            //沒(méi)有記錄,直接存入
            userLikeDetail.setCreateTime(LocalDateTime.now());
            userLikeDetailMapper.insert(userLikeDetail);
        }else{
            //有記錄,需要更新
            userLikeDetail.setStatus(item.getStatus());
            userLikeDetail.setUpdateTime(LocalDateTime.now());
            userLikeDetailMapper.updateById(item);
        }
    });
}

@Override
@Transactional
public void transLikedCountFromRedis2DB() {
    List<UserLikCountDTO> list = redisService.getLikedCountFromRedis();
    list.stream().forEach(item->{
        UserLikeCount user = userLikeCountMapper.selectById(item.getKey());
        //點(diǎn)贊數(shù)量屬于無(wú)關(guān)緊要的操作,出錯(cuò)無(wú)需拋異常
        if (user != null){
            Integer likeNum = user.getLikeNum() + item.getValue();
            user.setLikeNum(likeNum);
            //更新點(diǎn)贊數(shù)量
            userLikeCountMapper.updateById(user);
        }
    });
}

至此我們就實(shí)現(xiàn)了基于 Redis 的點(diǎn)贊功能,我們還需要注意一點(diǎn):查詢用戶點(diǎn)贊情況時(shí),需要同時(shí)查詢數(shù)據(jù)庫(kù)+緩存中的數(shù)據(jù)。

以上就是利用Redis實(shí)現(xiàn)點(diǎn)贊功能的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Redis點(diǎn)贊功能的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Redis使用Bitmap的方法實(shí)現(xiàn)

    Redis使用Bitmap的方法實(shí)現(xiàn)

    本文主要介紹了Redis使用Bitmap的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Redis中實(shí)現(xiàn)查找某個(gè)值的范圍

    Redis中實(shí)現(xiàn)查找某個(gè)值的范圍

    這篇文章主要介紹了Redis中實(shí)現(xiàn)查找某個(gè)值的范圍,本文的題引來(lái)了Redis作者Salvatore Sanfilippo(@antirez)的回答,比較經(jīng)典,需要的朋友可以參考下
    2015-06-06
  • Redis實(shí)現(xiàn)延遲任務(wù)的常見(jiàn)方案詳解

    Redis實(shí)現(xiàn)延遲任務(wù)的常見(jiàn)方案詳解

    延遲任務(wù)(Delayed?Task)是指在未來(lái)的某個(gè)時(shí)間點(diǎn),執(zhí)行相應(yīng)的任務(wù),本文為大家整理了Redis實(shí)現(xiàn)延遲任務(wù)的幾個(gè)常見(jiàn)方案,希望對(duì)大家有所幫助
    2024-04-04
  • redis搭建哨兵集群的實(shí)現(xiàn)步驟

    redis搭建哨兵集群的實(shí)現(xiàn)步驟

    本文主要介紹了redis搭建哨兵集群的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 一文搞懂阿里云服務(wù)器部署Redis并整合Spring?Boot

    一文搞懂阿里云服務(wù)器部署Redis并整合Spring?Boot

    這篇文章主要介紹了一文搞懂阿里云服務(wù)器部署Redis并整合Spring?Boot,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • 如何使用redis的setnx實(shí)現(xiàn)分布式鎖

    如何使用redis的setnx實(shí)現(xiàn)分布式鎖

    Redis Setnx(SET if Not eXists) 命令在指定的 key 不存在時(shí),為 key 設(shè)置指定的值,這篇文章主要介紹了使用redis的setnx實(shí)現(xiàn)分布式鎖,需要的朋友可以參考下
    2024-06-06
  • Windows環(huán)境下Redis Cluster環(huán)境搭建(圖文)

    Windows環(huán)境下Redis Cluster環(huán)境搭建(圖文)

    這篇文章主要介紹了Windows環(huán)境下Redis Cluster環(huán)境搭建(圖文),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • redis主從連接不成功錯(cuò)誤問(wèn)題及解決

    redis主從連接不成功錯(cuò)誤問(wèn)題及解決

    這篇文章主要介紹了redis主從連接不成功錯(cuò)誤問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教<BR>
    2024-01-01
  • redis實(shí)現(xiàn)加鎖的幾種方法示例詳解

    redis實(shí)現(xiàn)加鎖的幾種方法示例詳解

    這篇文章主要給大家介紹了關(guān)于redis實(shí)現(xiàn)加鎖的幾種方法,加鎖命令分別是INCR、SETNX和SET,文中給出了詳細(xì)的示例代碼,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • 淺析Redis?切片集群的數(shù)據(jù)傾斜問(wèn)題

    淺析Redis?切片集群的數(shù)據(jù)傾斜問(wèn)題

    如果?Redis?中的部署,采用的是切片集群,數(shù)據(jù)是會(huì)按照一定的規(guī)則分散到不同的實(shí)例中保存,比如,使用?Redis?Cluster?或?Codis,這篇文章主要介紹了Redis?切片集群的數(shù)據(jù)傾斜分析,需要的朋友可以參考下
    2022-06-06

最新評(píng)論

武宁县| 思南县| 嘉鱼县| 镇沅| 大英县| 绥中县| 巴东县| 内江市| 八宿县| 永修县| 定襄县| 商洛市| 时尚| 洛隆县| 郸城县| 怀集县| 丁青县| 光山县| 张家港市| 无为县| 应用必备| 雷山县| 兰溪市| 高清| 敦煌市| 通海县| 无棣县| 浮山县| 长汀县| 彝良县| 涿鹿县| 老河口市| 台中县| 揭阳市| 建昌县| 宜昌市| 陇川县| 内丘县| 汤原县| 临泉县| 都昌县|