色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

SpringBoot+Redis實現點贊功能的緩存和定時持久化(附源碼)

Android編程精選 ? 來源:CSDN ? 2023-02-09 16:38 ? 次閱讀

0.前言

本文基于Springboot利用Redis實現點贊功能的緩存和定時持久化接口

用戶對瀏覽內容進行【點贊/取贊】,并發送【點贊/取贊】請求到后端,這些信息先存入Redis中緩存,再每隔兩小時將Redis中的內容直接寫入數據庫持久化存儲。

1.項目目錄結構

5c54410e-a854-11ed-bfe3-dac502259ad0.png

2.Redis緩存點贊消息

1.設計思路

用戶點贊一條數據,設置狀態為0,并且更新被點贊內容的likeCount+1

用戶取消點贊一條數據,設置狀態為1,并且更新被點贊內容的likeCount+0

1.1 Redis鍵值對設計

選用Hash(散列)存儲

點贊信息

  • key: (String) 瀏覽信息id和點贊用戶id拼接而成, 分隔符為::
  • value: (HashMap) 存儲點贊狀態(0: 點贊 1:取消點贊)和更新時間的時間戳
  • key: "瀏覽信息id::點贊用戶id" value: {status: Integer, updateTime: long}

點贊數量

  • key: (String) 瀏覽信息id
  • value: (Integer) 點贊數量
5c6435e6-a854-11ed-bfe3-dac502259ad0.png5c83b010-a854-11ed-bfe3-dac502259ad0.png

1.2 點贊

5c9b0eb8-a854-11ed-bfe3-dac502259ad0.png
  • 用戶點贊信息,發送點贊請求到后端
  • 后端判斷該點贊信息在Redis中的狀態
    • Redis不進行存儲,并提醒前端重復存儲。
    • 更新/新增點贊信息
    • 更新/新增點贊量
    • 【不存在(沒有對應key) 】|| 【取消點贊(即取出的status為1)】
    • 【點贊(即取出的status為0,此時相當于重復點贊行為)】
  • 一次點贊請求完畢

1.3 取消點贊

5cb6a150-a854-11ed-bfe3-dac502259ad0.png
  • 用戶取消點贊信息,發送取消點贊請求到后端
  • 后端判斷該點贊信息在Redis中的狀態
    • 更新/新增點贊信息
    • 更新/新增點贊量
    • Redis不進行存儲,并提醒前端重復存儲。
    • 更新/新增點贊信息
    • 增加0條內容點贊量
    • 【不存在(沒有對應key) 】
    • 【取消點贊(即取出的status為1,此時相當于重復取消點贊行為)】
    • 【點贊(即取出的status為0)】
  • 一次取消點贊請求完畢

2.核心代碼實現

2.1 Redis封裝

具體實現參考該博客,不在贅述。

  • https://www.cnblogs.com/caizhaokai/p/11037610.html

2.2 工具類

1.時間戳轉化為LocalDateTime

importjava.time.Instant;
importjava.time.LocalDateTime;
importjava.time.ZoneId;

/**
*工具類:將時間戳轉化為LocalDateTime
*主要是因為redis不好存儲LocalDateTime,存儲timestamp方便一點,而且格式可以隨意改變
*/
publicclassLocalDateTimeConvertUtil{
publicstaticLocalDateTimegetDateTimeOfTimestamp(longtimestamp){
Instantinstant=Instant.ofEpochMilli(timestamp);
ZoneIdzone=ZoneId.systemDefault();
returnLocalDateTime.ofInstant(instant,zone);
}
}

2.RedisKey處理類

publicclassRedisKeyUtils{
/**
*
保存用戶點贊內容數據的key
*@date2021/9/2614:44
*/
publicstaticfinalStringMAP_KEY_USER_LIKED="MAP_USER_LIKED";
/**
*
保存內容被點贊數量的key
*@date2021/9/2614:44
*/
publicstaticfinalStringMAP_KEY_USER_LIKED_COUNT="MAP_USER_LIKED_COUNT";

/**
*拼接被點贊的內容id和點贊的人的id作為key。格式222222::333333
*@paraminfoId被點贊的內容id
*@paramlikeUserId點贊的人的id
*@return
*/
publicstaticStringgetLikedKey(StringinfoId,StringlikeUserId){
returninfoId+
"::"+
likeUserId;
}
}
2.3 DTO
//UserLikesDTO.java
@Data
@AllArgsConstructor
@NoArgsConstructor
publicclassUserLikesDTO{
privateStringinfoId;
privateStringlikeUserId;
privateIntegerstatus;
privateLocalDateTimeupdateTime;
}

//UserLikeCountDTO.java
@Data
@AllArgsConstructor
@NoArgsConstructor
publicclassUserLikeCountDTO{
privateStringinfoId;
privateIntegerlikeCount;
}
2.4 Service
  1. interface
//RedisService.java

importcom.csu.edu.redisLikeDemo.domain.DTO.UserLikeCountDTO;
importcom.csu.edu.redisLikeDemo.domain.DTO.UserLikesDTO;

importjava.util.List;

/**
*負責將數據寫入Redis緩存
*/
publicinterfaceRedisService{
/**
*獲取點贊狀態
*@paraminfoId
*@paramlikeUserId
*/
IntegergetLikeStatus(StringinfoId,StringlikeUserId);
/**
*點贊。狀態為1
*@paraminfoId
*@paramlikeUserId
*/
voidsaveLiked2Redis(StringinfoId,StringlikeUserId);

/**
*取消點贊。將狀態改變為0
*@paraminfoId
*@paramlikeUserId
*/
voidunlikeFromRedis(StringinfoId,StringlikeUserId);

/**
*從Redis中刪除一條點贊數據
*@paraminfoId
*@paramlikeUserId
*/
voiddeleteLikedFromRedis(StringinfoId,StringlikeUserId);

/**
*該內容的點贊數變化Δdelta
*@paraminfoId
*/
voidin_decrementLikedCount(StringinfoId,Integerdelta);

/**
*獲取Redis中存儲的所有點贊數據
*@return
*/
ListgetLikedDataFromRedis();

/**
*獲取Redis中存儲的所有點贊數量
*@return
*/
ListgetLikedCountFromRedis();
}
  1. implement
importcom.csu.edu.redisLikeDemo.common.CONSTANT;
importcom.csu.edu.redisLikeDemo.domain.DTO.UserLikeCountDTO;
importcom.csu.edu.redisLikeDemo.domain.DTO.UserLikesDTO;
importcom.csu.edu.redisLikeDemo.service.RedisService;
importcom.csu.edu.redisLikeDemo.util.LocalDateTimeConvertUtil;
importcom.csu.edu.redisLikeDemo.util.RedisKeyUtils;
importlombok.extern.slf4j.Slf4j;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.data.redis.core.Cursor;
importorg.springframework.data.redis.core.HashOperations;
importorg.springframework.data.redis.core.ScanOptions;
importorg.springframework.stereotype.Service;

importjava.time.LocalDateTime;
importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.List;
importjava.util.Map;

@Service("redisService")
@Slf4j
publicclassRedisServiceImplimplementsRedisService{

@Autowired
privateHashOperationsredisHash;//RedisHash

@Override
publicIntegergetLikeStatus(StringinfoId,StringlikeUserId){
if(redisHash.hasKey(RedisKeyUtils.MAP_KEY_USER_LIKED,RedisKeyUtils.getLikedKey(infoId,likeUserId))){
HashMapmap=(HashMap)redisHash.get(RedisKeyUtils.MAP_KEY_USER_LIKED,RedisKeyUtils.getLikedKey(infoId,likeUserId));
return(Integer)map.get("status");
}
returnCONSTANT.LikedStatusEum.NOT_EXIST.getCode();
}

@Override
publicvoidsaveLiked2Redis(StringinfoId,StringlikeUserId){
//生成key
Stringkey=RedisKeyUtils.getLikedKey(infoId,likeUserId);
//封裝value喜歡狀態更新時間
HashMapmap=newHashMap<>();
map.put("status",CONSTANT.LikedStatusEum.LIKE.getCode());
map.put("updateTime",System.currentTimeMillis());

redisHash.put(RedisKeyUtils.MAP_KEY_USER_LIKED,key,map);
}

@Override
publicvoidunlikeFromRedis(StringinfoId,StringlikeUserId){
//生成key
Stringkey=RedisKeyUtils.getLikedKey(infoId,likeUserId);
//封裝value喜歡狀態更新時間
HashMapmap=newHashMap<>();
map.put("status",CONSTANT.LikedStatusEum.UNLIKE.getCode());
map.put("updateTime",System.currentTimeMillis());//存入當前時間戳

redisHash.put(RedisKeyUtils.MAP_KEY_USER_LIKED,key,map);
}

@Override
publicvoiddeleteLikedFromRedis(StringinfoId,StringlikeUserId){
Stringkey=RedisKeyUtils.getLikedKey(infoId,likeUserId);
redisHash.delete(RedisKeyUtils.MAP_KEY_USER_LIKED,key);
}

@Override
publicvoidin_decrementLikedCount(StringinfoId,Integerdelta){
redisHash.increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT,infoId,delta);
}

@Override
publicListgetLikedDataFromRedis(){
//scan讀取數據,比key匹配優雅
Cursor>cursor=redisHash.scan(RedisKeyUtils.MAP_KEY_USER_LIKED,ScanOptions.NONE);

Listlist=newArrayList<>();
while(cursor.hasNext()){
Map.Entryentry=cursor.next();
Stringkey=(String)entry.getKey();
//分離出infoId,likedPostId,解析value
String[]split=key.split("::");
StringinfoId=split[0];
StringlikeUserId=split[1];
HashMapmap=(HashMap)entry.getValue();
Integerstatus=(Integer)map.get("status");
longupdateTimeStamp=(long)map.get("updateTime");
LocalDateTimeupdateTime=LocalDateTimeConvertUtil.getDateTimeOfTimestamp(updateTimeStamp);//時間戳轉為LocalDateTime

//組裝成UserLike對象
UserLikesDTOuserLikesDTO=newUserLikesDTO(infoId,likeUserId,status,updateTime);
list.add(userLikesDTO);

//存到list后從Redis中清理緩存
redisHash.delete(RedisKeyUtils.MAP_KEY_USER_LIKED,key);
}
returnlist;
}

@Override
publicListgetLikedCountFromRedis(){
//scan讀取數據,比key匹配優雅
Cursor>cursor=redisHash.scan(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT,ScanOptions.NONE);
Listlist=newArrayList<>();
while(cursor.hasNext()){
Map.Entrymap=cursor.next();
//將點贊數量存儲在LikedCountDT
Stringkey=(String)map.getKey();
UserLikeCountDTOdto=newUserLikeCountDTO(key,(Integer)map.getValue());
list.add(dto);
//從Redis中刪除這條記錄
redisHash.delete(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT,key);
}
returnlist;
}
}
2.5 controller & API
  1. controller
importcom.csu.edu.redisLikeDemo.common.CommonResponse;
importcom.csu.edu.redisLikeDemo.service.LikeService;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.web.bind.annotation.PostMapping;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test/")
publicclassLikeController{
@Autowired
privateLikeServicelikeService;

@PostMapping("like")
publicCommonResponselikeInfo(
StringinfoId,
StringuserId){
returnlikeService.likeInfo(infoId,userId);
}

@PostMapping("dislike")
publicCommonResponsedislikeInfo(
StringinfoId,
StringuserId){
returnlikeService.dislikeInfo(infoId,userId);
}
}

		
  1. 接口測試
5cde82ec-a854-11ed-bfe3-dac502259ad0.png5cde82ec-a854-11ed-bfe3-dac502259ad0.png5d0c3f52-a854-11ed-bfe3-dac502259ad0.png5d368bcc-a854-11ed-bfe3-dac502259ad0.png

3.Redis定時持久化

1.設計思路

1.1 數據庫設計

#瀏覽內容表
DROPTABLEIFEXISTS`view_item`;
CREATETABLE`view_item`(
`id`varchar(32)CHARACTERSETutf8COLLATEutf8_general_ciNOTNULLCOMMENT'內容id(如文章、短視頻等等)',
`create_user`varchar(50)CHARACTERSETutf8COLLATEutf8_general_ciNULLDEFAULTNULLCOMMENT'創建者',
`like_count`int(11)NULLDEFAULTNULLCOMMENT'點贊數',
`cmt_count`int(11)NULLDEFAULTNULLCOMMENT'評論數',
`share_count`int(11)NULLDEFAULTNULLCOMMENT'分享數',
`create_time`datetime(0)NULLDEFAULTNULLCOMMENT'創建時間',
`update_time`datetime(0)NULLDEFAULTNULLCOMMENT'更新時間',
PRIMARYKEY(`id`)USINGBTREE
)ENGINE=InnoDBCHARACTERSET=utf8COLLATE=utf8_general_ciROW_FORMAT=Dynamic;

SETFOREIGN_KEY_CHECKS=1;

#點贊-用戶表
DROPTABLEIFEXISTS`user_likes`;
CREATETABLE`user_likes`(
`id`varchar(32)CHARACTERSETutf8mb4COLLATEutf8mb4_general_ciNOTNULLCOMMENT'點贊信息ID',
`info_id`varchar(32)CHARACTERSETutf8mb4COLLATEutf8mb4_general_ciNULLDEFAULTNULLCOMMENT'點贊對象id',
`like_user_id`varchar(32)CHARACTERSETutf8mb4COLLATEutf8mb4_general_ciNULLDEFAULTNULLCOMMENT'點贊人ID',
`status`tinyint(4)NULLDEFAULT0COMMENT'0點贊1取消',
`create_time`datetime(0)NULLDEFAULTNULLCOMMENT'創建時間',
`update_time`datetime(0)NULLDEFAULTNULLCOMMENT'更新時間',
PRIMARYKEY(`id`)USINGBTREE,
UNIQUEINDEX`agdkey`(`like_user_id`,`info_id`)USINGBTREE
)ENGINE=InnoDBCHARACTERSET=utf8mb4COLLATE=utf8mb4_general_ciCOMMENT='點贊記錄表'ROW_FORMAT=Dynamic;
5d4bba4c-a854-11ed-bfe3-dac502259ad0.png5d5d2052-a854-11ed-bfe3-dac502259ad0.png

1.2 流程

5d792c34-a854-11ed-bfe3-dac502259ad0.png
  1. 遍歷Redis的【點贊信息】,僅改變數據庫中點贊信息的狀態
  2. 判斷當前點贊信息是否在數據庫中
  • 否,則更新數據
    • 數據庫中新增點贊-用戶記錄
    • 更新內容的點贊量
    • 轉到6
    • 轉到第3步
  1. 判斷數據庫中的點贊狀態與緩存中的點贊狀態(status)
  • 一致
    • 狀態不改變
    • 點贊數量-1(兩種情況邏輯分析有差異,但是最終結果均為-1)
    • 結束
  • 不一致,則需要針對具體情況改變
    • 轉到步驟4
  1. 判斷數據庫點贊狀態
  • 已經點贊,需要更改為取消點贊
    • 數據庫中修改為取消點贊狀態
    • 更新緩存中的點贊數量-1(減去數據庫中持久化的一個點贊量,一會兒緩存會和數據庫點贊總量加和)
  • 取消點贊,需要更改
    • 數據庫中修改為點贊狀態
    • 無需更新緩存中的點贊數量,因為緩存中已經+1(即該點贊數據的點贊量)
  1. 將緩存【點贊數量】持久化并清理緩存 此處修改數據庫中的點贊數量
  2. 完成緩存持久化

1.3定時寫入

使用 Quartz redis 定時任務持久化存儲到數據庫


<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-quartzartifactId>
dependency>

2.核心代碼實現

2.1Bean

importcom.baomidou.mybatisplus.annotation.TableField;
importcom.baomidou.mybatisplus.annotation.TableId;
importcom.baomidou.mybatisplus.annotation.TableName;
importlombok.Data;

importjava.time.LocalDateTime;

@Data
@TableName("user_likes")
publicclassUserLikes{
@TableId
privateStringid;
@TableField("info_id")
privateStringinfoId;
@TableField("like_user_id")
privateStringlikeUserId;

privateIntegerstatus;

@TableField("create_time")
privateLocalDateTimecreateTime;
@TableField("update_time")
privateLocalDateTimeupdateTime;
}
importcom.baomidou.mybatisplus.annotation.TableField;
importcom.baomidou.mybatisplus.annotation.TableId;
importcom.baomidou.mybatisplus.annotation.TableName;
importlombok.Data;

importjava.time.LocalDateTime;

@Data
@TableName("view_item")
publicclassViewItem{
@TableId
privateStringid;
@TableField("create_user")
privateStringcreateUser;

@TableField("like_count")
privateIntegerlikeCount;
@TableField("cmt_count")
privateIntegercmtCount;
@TableField("share_count")
privateIntegershareCount;

@TableField("create_time")
privateLocalDateTimecreateTime;
@TableField("update_time")
privateLocalDateTimeupdateTime;
}

2.2 Service

  1. interface
importcom.baomidou.mybatisplus.extension.plugins.pagination.Page;
importcom.csu.edu.redisLikeDemo.domain.UserLikes;

/**
*負責將Redis緩存中的數據持久化到數據庫中
*/
publicinterfaceDBService{
/**
*保存點贊記錄
*@paramuserLike
*@return
*/
Booleansave(UserLikesuserLike);
/**
*更新點贊記錄
*@paramuserLike
*@return
*/
Booleanupdate(UserLikesuserLike);
/**
*根據內容的id查詢點贊列表(即查詢都誰給這個內容點贊過)
*@paraminfoId內容的id
*@return
*/
PagegetLikedListByInfoId(StringinfoId,intpageNum,intpageSize);

/**
*根據點贊人的id查詢點贊列表(即查詢這個人都給哪些內容點贊過)
*@paramlikeUserId
*@return
*/
PagegetLikedListByLikeUserId(StringlikeUserId,intpageNum,intpageSize);

/**
*通過被點贊內容和點贊人id查詢是否存在點贊記錄
*@paraminfoId
*@paramlikeUserId
*@return
*/
UserLikesgetByInfoIdAndLikeUserId(StringinfoId,StringlikeUserId);

/**
*將Redis里的點贊數據存入數據庫中,True表示還需要進一步持久化,False表示數據庫中已存在該數據,無需進一步持久化
*/
voidtransLikedFromRedis2DB();

/**
*將Redis中的點贊數量數據存入數據庫
*/
voidtransLikedCountFromRedis2DB();
}
  1. implement
importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
importcom.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
importcom.baomidou.mybatisplus.extension.plugins.pagination.Page;
importcom.csu.edu.redisLikeDemo.common.CONSTANT;
importcom.csu.edu.redisLikeDemo.domain.DTO.UserLikeCountDTO;
importcom.csu.edu.redisLikeDemo.domain.DTO.UserLikesDTO;
importcom.csu.edu.redisLikeDemo.domain.UserLikes;
importcom.csu.edu.redisLikeDemo.domain.ViewItem;
importcom.csu.edu.redisLikeDemo.mapper.UserLikesMapper;
importcom.csu.edu.redisLikeDemo.mapper.ViewItemMapper;
importcom.csu.edu.redisLikeDemo.service.DBService;
importcom.csu.edu.redisLikeDemo.service.RedisService;
importlombok.extern.slf4j.Slf4j;
importorg.apache.commons.collections4.CollectionUtils;
importorg.n3r.idworker.Sid;
importorg.springframework.beans.BeanUtils;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.stereotype.Service;

importjava.time.LocalDateTime;
importjava.util.HashMap;
importjava.util.List;

@Service("dbService")
@Slf4j
publicclassDBServiceImplimplementsDBService{

@Autowired
privateRedisServiceredisService;
@Autowired
privateUserLikesMapperuserLikesMapper;
@Autowired
privateViewItemMapperviewItemMapper;
@Autowired
privateSidsid;//Id生成器,利用idWorker產生唯一(不重復)自增式的id,可以根據需求選用其他方式,比如MyBatisPlus的自增

@Override
publicBooleansave(UserLikesuserLike){
introws=userLikesMapper.insert(userLike);
returnrows>0;
}

@Override
publicBooleanupdate(UserLikesuserLike){
UpdateWrapperupdateWrapper=newUpdateWrapper<>();
updateWrapper.set("status",userLike.getStatus());
updateWrapper.set("update_time",userLike.getUpdateTime());
updateWrapper.eq("id",userLike.getId());

introws=userLikesMapper.update(userLike,updateWrapper);
returnrows>0;
}

@Override
publicPagegetLikedListByInfoId(StringinfoId,intpageNum,intpageSize){
//分頁獲取喜歡列表信息
Pageresult=newPage<>();
result.setCurrent(pageNum);
result.setSize(pageSize);

//獲取內容的id查詢點贊列表
QueryWrapperqueryWrapper=newQueryWrapper();
queryWrapper.eq("info_id",infoId);
result=userLikesMapper.selectPage(result,queryWrapper);
log.info("獲得內容的id查詢點贊列表(即查詢都有誰給這個內容點贊過)");
returnresult;
}

@Override
publicPagegetLikedListByLikeUserId(StringlikeUserId,intpageNum,intpageSize){
//分頁獲取喜歡列表信息
Pageresult=newPage<>();
result.setCurrent(pageNum);
result.setSize(pageSize);

//獲取用戶的id查詢點贊列表
QueryWrapperqueryWrapper=newQueryWrapper();
queryWrapper.eq("like_user_id",likeUserId);
result=userLikesMapper.selectPage(result,queryWrapper);
log.info("獲取點贊人的id查詢點贊列表(即查詢這個人都給哪些內容點贊過)");
returnresult;
}

@Override
publicUserLikesgetByInfoIdAndLikeUserId(StringinfoId,StringlikeUserId){
HashMapmap=newHashMap<>();
map.put("info_id",infoId);
map.put("like_user_id",likeUserId);
try{
UserLikesuserLikes=userLikesMapper.selectByMap(map).get(0);
log.info("通過被點贊人和點贊人id查詢是否存在點贊記錄");
returnuserLikes;
}catch(Exceptione){
log.info("當前查詢的被點贊人和點贊人id不存在點贊記錄");
returnnull;
}
}

@Override
publicvoidtransLikedFromRedis2DB(){
//批量獲取緩存中的點贊數據
Listlist=redisService.getLikedDataFromRedis();
if(CollectionUtils.isEmpty(list))//為空,不寫入
return;
for(UserLikesDTOitem:list){
UserLikesuserLikes=getByInfoIdAndLikeUserId(item.getInfoId(),item.getLikeUserId());//在數據庫中查詢
if(userLikes==null){//無記錄,新增
if(!save(userLikesDTOtoUserLikes(item))){
log.info("新增點贊數據失敗!");
return;
//System.out.println("緩存記錄寫入數據庫失敗!請重試");
}
}else{//有記錄,更新
//判斷數據庫中點贊狀態與緩存中點贊狀態一致性
if(userLikes.getStatus()==item.getStatus()){//一致,無需持久化,點贊數量-1
redisService.in_decrementLikedCount(item.getInfoId(),-1);
}else{//不一致
if(userLikes.getStatus()==CONSTANT.LikedStatusEum.LIKE.getCode()){//在數據庫中已經是點贊,則取消點贊,同時記得redis中的count-1
//之前是點贊,現在改為取消點贊1.設置更改status2.redis中的count要-1(消除在數據庫中自己的記錄)
userLikes.setStatus(CONSTANT.LikedStatusEum.UNLIKE.getCode());
redisService.in_decrementLikedCount(item.getInfoId(),-1);
}elseif(userLikes.getStatus()==CONSTANT.LikedStatusEum.UNLIKE.getCode()){//未點贊,則點贊,修改點贊狀態和點贊數據+1
userLikes.setStatus(CONSTANT.LikedStatusEum.LIKE.getCode());
redisService.in_decrementLikedCount(item.getInfoId(),1);
}
userLikes.setUpdateTime(LocalDateTime.now());
if(!update(userLikes)){//更新點贊數據
log.info("更新點贊數據失敗!");
return;
//System.out.println("緩存記錄更新數據庫失敗!請重試");
}
}
}
}
}

@Override
publicvoidtransLikedCountFromRedis2DB(){
//獲取緩存中內容的點贊數列表
Listlist=redisService.getLikedCountFromRedis();
if(CollectionUtils.isEmpty(list))//為空,不寫入
return;
for(UserLikeCountDTOitem:list){
ViewItemviewItem=viewItemMapper.selectById(item.getInfoId());
if(viewItem!=null){//新增點贊數
IntegerlikeCount=viewItem.getLikeCount()+item.getLikeCount();
System.out.println("內容id不為空,更新內容點贊數量");
viewItem.setLikeCount(likeCount);

UpdateWrapperupdateWrapper=newUpdateWrapper<>();
updateWrapper.set("like_count",viewItem.getLikeCount());
updateWrapper.eq("id",viewItem.getId());
introws=viewItemMapper.update(viewItem,updateWrapper);
if(rows>0){
System.out.println("成功更新內容點贊數!");
return;
}
}
System.out.println("內容id不存在,無法將緩存數據持久化!");
}
}

privateUserLikesuserLikesDTOtoUserLikes(UserLikesDTOuserLikesDTO){
UserLikesuserLikes=newUserLikes();
userLikes.setId(sid.nextShort());
BeanUtils.copyProperties(userLikesDTO,userLikes);
userLikes.setCreateTime(LocalDateTime.now());
userLikes.setUpdateTime(LocalDateTime.now());
returnuserLikes;
}
}

3. 定時更新數據庫

3.1 定時任務

importcom.csu.edu.redisLikeDemo.service.DBService;
importlombok.extern.slf4j.Slf4j;
importorg.quartz.JobExecutionContext;
importorg.quartz.JobExecutionException;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.scheduling.quartz.QuartzJobBean;

importjava.text.SimpleDateFormat;
importjava.util.Date;

/**
*定時任務
*/
@Slf4j
publicclassCronUtilextendsQuartzJobBean{
@Autowired
privateDBServicedbService;
privateSimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-ddHHss");

/**
*執行的定時任務
*/
@Override
protectedvoidexecuteInternal(JobExecutionContextcontext)throwsJobExecutionException{
log.info("LikeTask--------{}",sdf.format(newDate()));

//將Redis里的點贊信息同步到數據庫里
dbService.transLikedFromRedis2DB();
dbService.transLikedCountFromRedis2DB();
}
}

3.2 定時任務配置

設置每兩個小時更新一次數據庫

importcom.csu.edu.redisLikeDemo.util.CronUtil;
importorg.quartz.*;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;

/**
*開啟定時任務持久化存儲到數據庫
*/
@Configuration
publicclassQuartzConfig{
privatestaticfinalStringLIKE_TASK_IDENTITY="LikeTaskQuartz";
@Bean
publicJobDetailquartzDetail(){
returnJobBuilder.newJob(CronUtil.class).withIdentity(LIKE_TASK_IDENTITY).storeDurably().build();
}

@Bean
publicTriggerquartzTrigger(){
SimpleScheduleBuilderscheduleBuilder=SimpleScheduleBuilder.simpleSchedule()
//.withIntervalInSeconds(20)//設置時間周期單位秒
.withIntervalInHours(2)//兩個小時執行一次
.repeatForever();
returnTriggerBuilder.newTrigger().forJob(quartzDetail())
.withIdentity(LIKE_TASK_IDENTITY)
.withSchedule(scheduleBuilder)
.build();
}
}

4.項目源碼地址 & 參考

項目源碼:

  • https://github.com/WuYiheng-Og/redislike

參考:

  • https://cloud.tencent.com/developer/article/1445905

  • https://www.cnblogs.com/caizhaokai/p/11037610.html

審核編輯 :李倩
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 緩存
    +關注

    關注

    1

    文章

    245

    瀏覽量

    27058
  • 數據庫
    +關注

    關注

    7

    文章

    3903

    瀏覽量

    65816
  • spring
    +關注

    關注

    0

    文章

    340

    瀏覽量

    14901
  • Redis
    +關注

    關注

    0

    文章

    385

    瀏覽量

    11330
  • SpringBoot
    +關注

    關注

    0

    文章

    175

    瀏覽量

    324

原文標題:SpringBoot + Redis 實現點贊功能的緩存和定時持久化(附源碼)

文章出處:【微信號:AndroidPush,微信公眾號:Android編程精選】歡迎添加關注!文章轉載請注明出處。

收藏 0人收藏

    評論

    相關推薦
    熱點推薦

    Redis堅持持久方式概述

    Redis 持久
    發表于 09-25 17:04

    關于redis中數據存儲的機制解析

    不同于memcached等完全基于內存的緩存中間件,Redis同時還提供了持久功能,這也是為什么Red
    發表于 09-02 10:46 ?1167次閱讀
    關于<b class='flag-5'>redis</b>中數據存儲的機制解析

    Springboot+redis操作多種實現

    一、Jedis,Redisson,Lettuce三者的區別共同點:都提供了基于Redis操作的Java API,只是封裝程度,具體實現稍有不同。 不同點: 1.1、Jedis 是Redis的Java
    的頭像 發表于 09-22 10:48 ?2021次閱讀
    <b class='flag-5'>Springboot+redis</b>操作多種<b class='flag-5'>實現</b>

    Redis持久機制的實現原理和使用技巧

    Redis將數據存儲在內存中,宕機或重啟都會使內存數據全部丟失, Redis持久機制用來保證數據不會因為故障而丟失。
    的頭像 發表于 09-13 16:42 ?1193次閱讀

    Redis持久化分為兩種:RDB和AOF

    Redis持久,一個老掉牙的問題,但是面試官就是喜歡問。這也是我們學Redis必會的一個知識
    的頭像 發表于 02-21 09:22 ?893次閱讀

    基于SpringBoot+Redis的轉盤抽獎

    基于SpringBoot+Redis等技術實現轉盤抽獎活動項目,含前端、后臺及數據庫文件
    的頭像 發表于 02-28 14:24 ?1879次閱讀
    基于<b class='flag-5'>SpringBoot+Redis</b>的轉盤抽獎

    如何在SpringBoot中解決Redis緩存穿透等問題

    今天給大家介紹一下如何在SpringBoot中解決Redis緩存穿透、緩存擊穿、緩存雪崩的問題。
    的頭像 發表于 04-28 11:35 ?905次閱讀

    如何用Springboot整合Redis

    docker exec -it redis redis-cli 注意:新版本redis6.0 默認開啟了混合持久,重啟
    的頭像 發表于 10-08 14:56 ?778次閱讀
    如何用<b class='flag-5'>Springboot</b>整合<b class='flag-5'>Redis</b>

    Redis持久機制介紹

    Redis持久機制? 為了能夠重用Redis數據,或者防止系統故障,我們需要將Redis中的數據寫入到磁盤空間中,即
    的頭像 發表于 10-09 11:44 ?673次閱讀
    <b class='flag-5'>Redis</b><b class='flag-5'>持久</b><b class='flag-5'>化</b>機制介紹

    Redis持久RDB方式介紹

    Redis持久 Redis是一個內存數據庫,為了保證數據的持久性,它提供了兩種持久
    的頭像 發表于 10-09 14:56 ?701次閱讀
    <b class='flag-5'>Redis</b><b class='flag-5'>持久</b><b class='flag-5'>化</b>RDB方式介紹

    redis兩種持久方式的區別

    Redis是一款高性能、開源的鍵值存儲數據庫,它支持多種數據結構,并且具有高效的內存讀寫以及持久功能Redis
    的頭像 發表于 12-04 11:12 ?691次閱讀

    redis持久方式RDB和AOF的區別

    Redis 是一個高性能的鍵值對數據庫,提供了兩種持久方式:RDB 和 AOF。RDB 是將 Redis 的數據快照保存到磁盤上,而 AOF 則是將
    的頭像 發表于 12-04 16:25 ?1058次閱讀

    redis持久機制和如何實現持久

    File)。 RDB是Redis默認采用的持久方式,它通過在指定時間間隔內將內存中的數據集快照寫入到磁盤的二進制文件中,實現數據的
    的頭像 發表于 12-05 10:02 ?627次閱讀

    redis持久機制優缺點

    Redis是一個基于內存的高性能鍵值存儲系統,它提供了多種持久機制來保證數據的可靠性。本文將詳細介紹Redis持久
    的頭像 發表于 12-05 10:03 ?973次閱讀

    云容器redis持久配置

    云容器技術為企業帶來了很多好處,包括高度可擴展性、靈活性和可移植性。其中一個常見的容器應用是Redis,一種高性能的鍵值對存儲系統。在云環境中,保證Redis數據的
    的頭像 發表于 12-05 10:07 ?689次閱讀
    主站蜘蛛池模板: 亚洲AV中文字幕无码久久 | 麻花传媒MD0044视频 | 邓奴的视频IVK | 伊人久久网国产伊人 | av天堂网2014在线 | 成人国产精品日本在线 | 人人碰在线视频 | 紧缚束缚调教丨vk | 真人做受120分钟免费看 | 在线伦理电影网 | 少妇连续高潮抽搐痉挛昏厥 | 动漫护士被乳羞羞漫 | 国内精品偷拍在线观看 | 一本之道加勒比在线观看 | 亚洲国产日韩制服在线观看 | 狠狠色色综合站 | 国产在线亚洲精品观 | 亚洲国产综合另类视频 | 色多多旧版污污破解版 | 国产精品无码久久久久不卡 | 久久免费看少妇级毛片蜜臀 | 精品无码国产自产在线观看水浒传 | 久久综合色一综合色88 | 九色PORNY蝌蚪视频首页 | 久久亚洲精品AV成人无码 | 婷婷久久综合九色综合伊人色 | 暗卫受被肉到失禁各种PLAY | 狠狠久久免费视频在线 | 中文字幕精品在线观看 | 好想被狂躁A片免费久99 | 精选国产AV精选一区二区三区 | 国产av在线看的 | 欧美高清videos 360p | 撕烂衣服扒开胸罩揉爆胸 | 九九久久久2 | 有人有片的观看免费视频 | 拔萝卜电视剧高清免费 | 92午夜免费福利757 | 国产免费毛片在线观看 | 夫妻性姿势真人做视频 | 一区在线观看在线 |

    電子發燒友

    中國電子工程師最喜歡的網站

    • 2931785位工程師會員交流學習
    • 獲取您個性化的科技前沿技術信息
    • 參加活動獲取豐厚的禮品