java實現點贊功能
本文實例為大傢分享瞭java實現點贊功能的具體代碼,供大傢參考,具體內容如下
實現思路:
將點贊的數據先保存到redis中,然後定時同步到數據庫
第一步:
在redis中創建二個hash 用於存儲 用戶點贊記錄及記錄點贊數
MAP_USER_LIKED :用戶點贊的記錄 key:記錄id::用戶id value:1
MAP_USER_LIKED_COUNT:記錄點贊數 key: 記錄id value:數量
第二步:
創建枚舉類
@Getter public enum LikeStatusEnum { LIKE(1,"點贊"), UNLIKE(0,"取消點贊/未點贊"); private Integer code; private String msg; LikeStatusEnum(Integer code,String msg){ this.code = code; this.msg = msg; } }
@Getter public enum RedisHashEnum { MAP_USER_LIKED("MAP_USER_LIKED"), MAP_USER_LIKED_COUNT("MAP_USER_LIKED_COUNT"); private String value; RedisHashEnum(String value){ this.value =value; } }
第三步:
將實現類寫好
@Service public class PostRedisServiceImpl implements PostRedisService { @Resource private RedisTemplate redisTemplate; @Autowired(required = false) public void setRedisTemplate(RedisTemplate redisTemplate){ RedisSerializer serializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(serializer); redisTemplate.setValueSerializer(serializer); redisTemplate.setHashKeySerializer(serializer); redisTemplate.setHashValueSerializer(serializer); this.redisTemplate = redisTemplate; } /** * 點贊、取消點贊 * * @param recordId * @param userId */ @Override public void saveLikeRedis(String recordId, String userId,Integer status) { String key =recordId+"::"+userId; redisTemplate.opsForHash().put(RedisHashEnum.MAP_USER_LIKED,key, status); } /** * 從Redis中刪除一條點贊數 * * @param recordId * @param userId */ @Override public void deleteLikeFromRedis(String recordId, String userId) { String key =recordId+"::"+userId; redisTemplate.opsForHash().delete(RedisHashEnum.MAP_USER_LIKED,key); } /** * 該記錄 點贊加1 * * @param recordId */ @Override public void incrementLikedCount(String recordId) { redisTemplate.opsForHash().increment(RedisHashEnum.MAP_USER_LIKED_COUNT,recordId,1); } /** * 譔記錄 點贊減1 * * @param recordId */ @Override public void decrementLikeCount(String recordId) { redisTemplate.opsForHash().increment(RedisHashEnum.MAP_USER_LIKED_COUNT,recordId,-1); } }
第四步提供接口:
/** * 進行點贊、取消點贊 * * @param vo */ @Override public Result addKudos(KudosVo vo) { if(vo == null){ return Result.error(ResponseMessage.PARAMERROR); } if("1".equals(vo.getStatus())){ // 點贊 postRedisService.saveLikeRedis(vo.getRecordId(),vo.getUserId(), LikeStatusEnum.LIKE.getCode()); // 記錄+1 postRedisService.incrementLikedCount(vo.getRecordId()); }else if("0".equals(vo.getStatus())){ // 取消點贊 更新狀態 postRedisService.saveLikeRedis(vo.getRecordId(),vo.getUserId(), LikeStatusEnum.UNLIKE.getCode()); // postRedisService.deleteLikeFromRedis(vo.getRecordId(),vo.getUserId()); // 記錄 -1 postRedisService.decrementLikeCount(vo.getRecordId()); } return Result.success(ResponseMessage.SUCCESS); }
最後定時將redis 中的數據同步到數據庫
/**每 5 分鐘執行一次 * 將點贊人員同步到庫中 * */ // @Transactional(rollbackFor =Exception.class) @Scheduled(cron = "0 */5 * * * ?") public void transLikdedFromRedis()throws IOException{ List<RedisLikedUserDTO> dtoList = getLikedUserFromRedis(); dtoList.stream().forEach(x->{ // 通過記錄及人員id 查詢 該 人員是否點贊 LambdaQueryWrapper<WorkCircleRecord> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(WorkCircleRecord::getDeleteIf,true); queryWrapper.eq(WorkCircleRecord::getId,x.getRecordId()); queryWrapper.like(WorkCircleRecord::getWorkKudosUserIds,x.getUserId()); WorkCircleRecord record = workCircleRecordMapper.selectOne(queryWrapper); // 點贊 if(record == null&&"1".equals(x.getStatus())){ // 根據記錄id 查詢 LambdaQueryWrapper<WorkCircleRecord> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(WorkCircleRecord::getDeleteIf,true); wrapper.eq(WorkCircleRecord::getId,x.getRecordId()); WorkCircleRecord workCircleRecord = workCircleRecordMapper.selectOne(wrapper); if(workCircleRecord != null){ // 沒有此人員 添加 if(StringUtils.isBlank(workCircleRecord.getWorkKudosUserIds())){ // 沒有點贊人員 workCircleRecord.setWorkKudosUserIds(x.getUserId()); SysUser user = sysUserMapper.selectById(x.getUserId()); if(user !=null){ workCircleRecord.setWorkKudosUser(user.getRealname()); } }else { // 有點贊人員 String userIds = x.getUserId()+","+workCircleRecord.getWorkKudosUserIds(); workCircleRecord.setWorkKudosUserIds(userIds); SysUser user = sysUserMapper.selectById(x.getUserId()); String userNames = user.getRealname()+workCircleRecord.getWorkKudosUser(); workCircleRecord.setWorkKudosUser(userNames); } workCircleRecordMapper.updateById(workCircleRecord); } }else if("0".equals(x.getStatus())) { // 有記錄 並取消點贊 // 根據記錄id 查詢 LambdaQueryWrapper<WorkCircleRecord> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(WorkCircleRecord::getDeleteIf,true); wrapper.eq(WorkCircleRecord::getId,x.getRecordId()); WorkCircleRecord workCircleRecord = workCircleRecordMapper.selectOne(wrapper); // 將此點贊人員去除 if(workCircleRecord !=null){ SysUser user = sysUserMapper.selectById(x.getUserId()); List<String> userIds = Arrays.asList(workCircleRecord.getWorkKudosUserIds().split(",")); List<String> userNames =Arrays.asList(workCircleRecord.getWorkKudosUser().split(",")); userIds.remove(x.getUserId()); userNames.remove(user.getRealname()); workCircleRecord.setWorkKudosUserIds(String.join(",",userIds)); workCircleRecord.setWorkKudosUser(String.join(",",userNames)); workCircleRecordMapper.updateById(workCircleRecord); } } }); }
/**獲取 所有點贊的人員 * */ public List<RedisLikedUserDTO> getLikedUserFromRedis() throws IOException{ List<RedisLikedUserDTO> dtoList = new ArrayList<>(); // 通過遊標獲取所有鍵值對 Cursor<Map.Entry<Object,Object>> cursor = redisTemplate.opsForHash().scan(RedisHashEnum.MAP_USER_LIKED.getValue(),ScanOptions.NONE); while (cursor.hasNext()){ Map.Entry<Object,Object> map = cursor.next(); String key = map.getKey().toString(); String[] split = key.split("::"); RedisLikedUserDTO dto = new RedisLikedUserDTO(); dto.setRecordId(split[0]); dto.setUserId(split[1]); dto.setStatus(Integer.parseInt(map.getValue().toString())); dtoList.add(dto); // 將redis 中的記錄刪除 redisTemplate.opsForHash().delete(RedisHashEnum.MAP_USER_LIKED.getValue(),key); } cursor.close(); return dtoList; }
/**每 5 分鐘執行一次 * 將點贊數同步到庫中 * */ @Transactional(rollbackFor =Exception.class) @Scheduled(cron = "0 */5 * * * ?") public void transLikedCountFromRedis() throws IOException{ // 獲取所有的點贊數 List<RedisLikeCountDTO> dtoList = getLikedCountFromRedis(); // 獲取所有的記錄id List<String> recordIdList = dtoList.stream().map(x->x.getRecordId()).collect(Collectors.toList()); if(CollectionUtils.isNotEmpty(recordIdList)){ List<WorkCircleRecord> recordList = workCircleRecordMapper.selectBatchIds(recordIdList); if(CollectionUtils.isNotEmpty(recordList)){ // 通過id 匹配 dtoList.stream().forEach(x->{ recordList.stream().forEach(k->{ if(x.getRecordId().equals(k.getId())){ Integer num = x.getCount()+k.getWorkKudos(); if(num<0){ k.setWorkKudos(0); }else { k.setWorkKudos(num); } workCircleRecordMapper.updateById(k); } }); }); } } }
/** 取出所有的點贊數 * */ public List<RedisLikeCountDTO> getLikedCountFromRedis() throws IOException { List<RedisLikeCountDTO> dtoList = new ArrayList<>(); Cursor<Map.Entry<Object,Object>> cursor= redisTemplate.opsForHash().scan(RedisHashEnum.MAP_USER_LIKED_COUNT, ScanOptions.NONE); while (cursor.hasNext()){ Map.Entry<Object,Object> map = cursor.next(); // 獲取 點贊數 String key = map.getKey().toString(); RedisLikeCountDTO dto = new RedisLikeCountDTO(); dto.setRecordId(key); dto.setCount(Integer.parseInt(map.getValue().toString())); dtoList.add(dto); redisTemplate.opsForHash().delete(RedisHashEnum.MAP_USER_LIKED_COUNT,key); } cursor.close(); return dtoList; }
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Java實現RedisUtils操作五大集合(增刪改查)
- Mapper層繼承BaseMapper<T>需要引入的pom依賴方式
- RedisTemplate常用方法總結
- SpringBoot整合Mysql和Redis的詳細過程
- SpringBoot整合Redis及Redis工具類撰寫實例